This commit is contained in:
Horis
2025-03-07 11:21:27 +08:00
parent 64f82edc2e
commit ffafa0cdfc
4 changed files with 59 additions and 84 deletions
@@ -65,7 +65,6 @@ object ReadManga : CoroutineScope by MainScope() {
val downloadFailChapters = hashMapOf<Int, Int>() val downloadFailChapters = hashMapOf<Int, Int>()
val downloadScope = CoroutineScope(SupervisorJob() + IO) val downloadScope = CoroutineScope(SupervisorJob() + IO)
var rateLimiter = ConcurrentRateLimiter(null) var rateLimiter = ConcurrentRateLimiter(null)
val durChapterAbsPos get() = (prevMangaChapter?.contents?.size ?: 0) + durChapterPos + 1
val mangaContents get() = buildContentList() val mangaContents get() = buildContentList()
val hasNextChapter get() = durChapterIndex < simulatedChapterSize - 1 val hasNextChapter get() = durChapterIndex < simulatedChapterSize - 1
@@ -235,35 +234,6 @@ object ReadManga : CoroutineScope by MainScope() {
} }
} }
/**
* 注册回调
*/
fun register(cb: Callback) {
mCallback = cb
}
/**
* 取消注册回调
*/
fun unregister(cb: Callback) {
if (mCallback === cb) {
mCallback = null
}
inBookshelf = false
tocChanged = false
chapterChanged = false
durChapterIndex = 0
chapterSize = 0
durChapterPos = 0
durChapterImageCount = 0
simulatedChapterSize = 0
preDownloadTask?.cancel()
preDownloadTask = null
downloadScope.coroutineContext.cancelChildren()
coroutineContext.cancelChildren()
}
/** /**
* 内容加载完成 * 内容加载完成
*/ */
@@ -276,7 +246,7 @@ object ReadManga : CoroutineScope by MainScope() {
if (chapter.index !in durChapterIndex - 1..durChapterIndex + 1) { if (chapter.index !in durChapterIndex - 1..durChapterIndex + 1) {
return return
} }
when (chapter.index - durChapterIndex) { when (val offset = chapter.index - durChapterIndex) {
0 -> { 0 -> {
if (content == null) { if (content == null) {
mCallback?.loadFail("加载内容失败") mCallback?.loadFail("加载内容失败")
@@ -294,10 +264,9 @@ object ReadManga : CoroutineScope by MainScope() {
durChapterImageCount = mangaChapter.imageCount durChapterImageCount = mangaChapter.imageCount
curMangaChapter = mangaChapter curMangaChapter = mangaChapter
mCallback?.upContent(true) mCallback?.upContent(true)
mCallback?.contentLoadFinish()
} }
-1 -> { -1, 1 -> {
if (content == null || content.isEmpty()) { if (content == null || content.isEmpty()) {
return return
} }
@@ -305,27 +274,22 @@ object ReadManga : CoroutineScope by MainScope() {
if (mangaChapter.imageCount == 0) { if (mangaChapter.imageCount == 0) {
return return
} }
prevMangaChapter = mangaChapter
mCallback?.upContent() when (offset) {
-1 -> prevMangaChapter = mangaChapter
1 -> nextMangaChapter = mangaChapter
} }
1 -> {
if (content == null || content.isEmpty()) {
return
}
val mangaChapter = getManageChapter(chapter, content)
if (mangaChapter.imageCount == 0) {
return
}
nextMangaChapter = mangaChapter
mCallback?.upContent() mCallback?.upContent()
} }
} }
} }
private fun buildContentList(): List<Any> { private fun buildContentList(): Pair<Int, List<Any>> {
val list = arrayListOf<Any>() val list = arrayListOf<Any>()
var pos = durChapterPos + 1
prevMangaChapter?.let { prevMangaChapter?.let {
pos += it.contents.size
list.addAll(it.contents) list.addAll(it.contents)
} }
curMangaChapter?.let { curMangaChapter?.let {
@@ -334,19 +298,20 @@ object ReadManga : CoroutineScope by MainScope() {
nextMangaChapter?.let { nextMangaChapter?.let {
list.addAll(it.contents) list.addAll(it.contents)
} }
return list return pos to list
} }
/** /**
* 加载下一章 * 加载下一章
*/ */
fun moveToNextChapter(): Boolean { fun moveToNextChapter(startLoad: () -> Unit): Boolean {
if (durChapterIndex < simulatedChapterSize - 1) { if (durChapterIndex < simulatedChapterSize - 1) {
durChapterIndex++ durChapterIndex++
prevMangaChapter = curMangaChapter prevMangaChapter = curMangaChapter
curMangaChapter = nextMangaChapter curMangaChapter = nextMangaChapter
nextMangaChapter = null nextMangaChapter = null
if (curMangaChapter == null) { if (curMangaChapter == null) {
startLoad.invoke()
loadContent(durChapterIndex) loadContent(durChapterIndex)
} else { } else {
mCallback?.upContent(true) mCallback?.upContent(true)
@@ -548,6 +513,26 @@ object ReadManga : CoroutineScope by MainScope() {
} }
} }
/**
* 注册回调
*/
fun register(cb: Callback) {
mCallback = cb
}
/**
* 取消注册回调
*/
fun unregister(cb: Callback) {
if (mCallback === cb) {
mCallback = null
}
preDownloadTask?.cancel()
preDownloadTask = null
downloadScope.coroutineContext.cancelChildren()
coroutineContext.cancelChildren()
}
private suspend fun getManageChapter(chapter: BookChapter, content: String): MangaChapter { private suspend fun getManageChapter(chapter: BookChapter, content: String): MangaChapter {
val list = flow { val list = flow {
val matcher = AppPattern.imgPattern.matcher(content) val matcher = AppPattern.imgPattern.matcher(content)
@@ -595,7 +580,6 @@ object ReadManga : CoroutineScope by MainScope() {
interface Callback { interface Callback {
fun upContent(finish: Boolean = false) fun upContent(finish: Boolean = false)
fun contentLoadFinish()
fun loadFail(msg: String) fun loadFail(msg: String)
fun adjustProgress() fun adjustProgress()
fun sureNewProgress(progress: BookProgress) fun sureNewProgress(progress: BookProgress)
@@ -122,8 +122,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
private val loadMoreView by lazy { private val loadMoreView by lazy {
LoadMoreView(this).apply { LoadMoreView(this).apply {
setBackgroundColor(getCompatColor(R.color.book_ant_10)) setBackgroundColor(getCompatColor(R.color.book_ant_10))
getLoading().loadingColor = getCompatColor(R.color.white) setLoadingColor(R.color.white)
getLoadingText().setTextColor(getCompatColor(R.color.white)) setLoadingTextColor(R.color.white)
} }
} }
@@ -208,11 +208,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
val content = mAdapter.getItem(position) val content = mAdapter.getItem(position)
if (content is MangaContent) { if (content is MangaContent) {
if (ReadManga.durChapterIndex < content.mChapterIndex) { if (ReadManga.durChapterIndex < content.mChapterIndex) {
ReadManga.moveToNextChapter() ReadManga.moveToNextChapter {
if (ReadManga.hasNextChapter) {
loadMoreView.startLoad() loadMoreView.startLoad()
} else {
loadMoreView.noMore("暂无章节了!")
} }
} else if (ReadManga.durChapterIndex > content.mChapterIndex) { } else if (ReadManga.durChapterIndex > content.mChapterIndex) {
ReadManga.moveToPrevChapter() ReadManga.moveToPrevChapter()
@@ -262,7 +259,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
override fun upContent(finish: Boolean) { override fun upContent(finish: Boolean) {
lifecycleScope.launch { lifecycleScope.launch {
setTitle(ReadManga.book?.name) setTitle(ReadManga.book?.name)
val list = withContext(IO) { ReadManga.mangaContents } val (pos, list) = withContext(IO) { ReadManga.mangaContents }
mAdapter.submitList(list) { mAdapter.submitList(list) {
if (loadingViewVisible && finish) { if (loadingViewVisible && finish) {
binding.infobar.isVisible = true binding.infobar.isVisible = true
@@ -273,7 +270,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
ReadManga.durChapterImageCount, ReadManga.durChapterImageCount,
ReadManga.curMangaChapter!!.chapter.title ReadManga.curMangaChapter!!.chapter.title
) )
binding.mRecyclerManga.scrollToPosition(ReadManga.durChapterAbsPos) binding.mRecyclerManga.scrollToPosition(pos)
binding.flLoading.isGone = true binding.flLoading.isGone = true
loadMoreView.visible() loadMoreView.visible()
} }
@@ -286,7 +283,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
} }
if (ReadManga.chapterChanged) { if (ReadManga.chapterChanged) {
binding.mRecyclerManga.scrollToPosition(ReadManga.durChapterAbsPos) binding.mRecyclerManga.scrollToPosition(pos)
} }
ReadManga.chapterChanged = false ReadManga.chapterChanged = false
@@ -294,12 +291,6 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangaBinding, ReadMangaViewMode
} }
} }
override fun contentLoadFinish() {
lifecycleScope.launch {
loadMoreView.stopLoad()
}
}
private fun upInfoBar( private fun upInfoBar(
chapterIndex: Int, chapterIndex: Int,
chapterSize: Int, chapterSize: Int,
@@ -31,6 +31,8 @@ import java.util.Collections
class MangaAdapter(private val context: Context) : class MangaAdapter(private val context: Context) :
RecyclerView.Adapter<RecyclerView.ViewHolder>(), PreloadModelProvider<Any> { RecyclerView.Adapter<RecyclerView.ViewHolder>(), PreloadModelProvider<Any> {
private val inflater: LayoutInflater = LayoutInflater.from(context)
companion object { companion object {
private const val LOADING_VIEW = 0 private const val LOADING_VIEW = 0
private const val CONTENT_VIEW = 1 private const val CONTENT_VIEW = 1
@@ -85,13 +87,15 @@ class MangaAdapter(private val context: Context) :
binding.retry.setOnClickListener { binding.retry.setOnClickListener {
val item = mDiffer.currentList[layoutPosition] val item = mDiffer.currentList[layoutPosition]
if (item is MangaContent) { if (item is MangaContent) {
loadImageWithRetry(item.mImageUrl, isHorizontal, mDiffer.currentList.size == 3) loadImageWithRetry(
item.mImageUrl, isHorizontal, item.mDurChapterImageCount == 1
)
} }
} }
} }
fun onBind(item: MangaContent) { fun onBind(item: MangaContent) {
loadImageWithRetry(item.mImageUrl, isHorizontal, mDiffer.currentList.size == 3) loadImageWithRetry(item.mImageUrl, isHorizontal, item.mDurChapterImageCount == 1)
} }
} }
@@ -105,29 +109,18 @@ class MangaAdapter(private val context: Context) :
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when { return when {
viewType >= TYPE_FOOTER_VIEW -> { viewType >= TYPE_FOOTER_VIEW -> {
ItemViewHolder(footerItems.get(viewType).invoke(parent)) ItemViewHolder(footerItems.get(viewType).invoke(parent))
} }
viewType == LOADING_VIEW -> PageMoreViewHolder( viewType == LOADING_VIEW -> {
BookComicLoadingRvBinding.inflate( PageMoreViewHolder(BookComicLoadingRvBinding.inflate(inflater, parent, false))
LayoutInflater.from( }
parent.context
), parent, false
)
)
viewType == CONTENT_VIEW -> PageViewHolder(
BookComicRvBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
viewType == CONTENT_VIEW -> {
PageViewHolder(BookComicRvBinding.inflate(inflater, parent, false))
}
else -> error("Unknown view type!") else -> error("Unknown view type!")
} }
@@ -5,9 +5,11 @@ import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.annotation.ColorRes
import io.legado.app.R import io.legado.app.R
import io.legado.app.databinding.ViewLoadMoreBinding import io.legado.app.databinding.ViewLoadMoreBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.utils.getCompatColor
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import io.legado.app.utils.visible import io.legado.app.utils.visible
@@ -79,8 +81,13 @@ class LoadMoreView(context: Context, attrs: AttributeSet? = null) : FrameLayout(
binding.tvText.visible() binding.tvText.visible()
} }
fun getLoading() = binding.rotateLoading fun setLoadingColor(@ColorRes color: Int) {
fun getLoadingText() = binding.tvText binding.rotateLoading.loadingColor = context.getCompatColor(color)
}
fun setLoadingTextColor(@ColorRes color: Int) {
binding.tvText.setTextColor(context.getCompatColor(color))
}
private fun showErrorDialog(): Boolean { private fun showErrorDialog(): Boolean {
if (errorMsg.isBlank()) { if (errorMsg.isBlank()) {