This commit is contained in:
Horis
2025-03-08 13:18:28 +08:00
parent bbb6ac6815
commit 68349a01be
10 changed files with 97 additions and 30 deletions
@@ -153,6 +153,8 @@ object ReadBook : CoroutineScope by MainScope() {
upWebBook(book) upWebBook(book)
synchronized(this) { synchronized(this) {
loadingChapters.clear() loadingChapters.clear()
downloadedChapters.clear()
downloadFailChapters.clear()
} }
} }
@@ -615,7 +617,7 @@ object ReadBook : CoroutineScope by MainScope() {
val book = book ?: return val book = book ?: return
val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, index) ?: return val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, index) ?: return
if (BookHelp.hasContent(book, chapter)) { if (BookHelp.hasContent(book, chapter)) {
addDownloadedChapter(chapter.index) downloadedChapters.add(chapter.index)
} else { } else {
delay(1000) delay(1000)
if (addLoading(index)) { if (addLoading(index)) {
@@ -673,11 +675,6 @@ object ReadBook : CoroutineScope by MainScope() {
loadingChapters.remove(index) loadingChapters.remove(index)
} }
@Synchronized
fun addDownloadedChapter(index: Int) {
downloadedChapters.add(index)
}
/** /**
* 内容加载完成 * 内容加载完成
*/ */
@@ -13,6 +13,7 @@ import io.legado.app.help.ConcurrentRateLimiter
import io.legado.app.help.book.BookHelp import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.ContentProcessor import io.legado.app.help.book.ContentProcessor
import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocal
import io.legado.app.help.book.isSameNameAuthor
import io.legado.app.help.book.readSimulating import io.legado.app.help.book.readSimulating
import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.book.simulatedTotalChapterNum
import io.legado.app.help.book.update import io.legado.app.help.book.update
@@ -108,6 +109,8 @@ object ReadManga : CoroutineScope by MainScope() {
upWebBook(book) upWebBook(book)
synchronized(this) { synchronized(this) {
loadingChapters.clear() loadingChapters.clear()
downloadedChapters.clear()
downloadFailChapters.clear()
} }
} }
@@ -151,11 +154,6 @@ object ReadManga : CoroutineScope by MainScope() {
loadingChapters.remove(index) loadingChapters.remove(index)
} }
@Synchronized
fun addDownloadedChapter(index: Int) {
downloadedChapters.add(index)
}
fun loadContent() { fun loadContent() {
clearMangaChapter() clearMangaChapter()
loadContent(durChapterIndex) loadContent(durChapterIndex)
@@ -403,7 +401,7 @@ object ReadManga : CoroutineScope by MainScope() {
val book = book ?: return val book = book ?: return
val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, index) ?: return val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, index) ?: return
if (BookHelp.hasContent(book, chapter)) { if (BookHelp.hasContent(book, chapter)) {
addDownloadedChapter(chapter.index) downloadedChapters.add(chapter.index)
} else { } else {
delay(1000) delay(1000)
if (addLoading(index)) { if (addLoading(index)) {
@@ -530,6 +528,18 @@ object ReadManga : CoroutineScope by MainScope() {
mCallback?.showLoading() mCallback?.showLoading()
} }
fun onChapterListUpdated(newBook: Book) {
if (newBook.isSameNameAuthor(book)) {
book = newBook
chapterSize = newBook.totalChapterNum
simulatedChapterSize = newBook.simulatedTotalChapterNum()
if (simulatedChapterSize > 0 && durChapterIndex > simulatedChapterSize - 1) {
durChapterIndex = simulatedChapterSize - 1
}
clearMangaChapter()
}
}
/** /**
* 注册回调 * 注册回调
*/ */
@@ -32,6 +32,7 @@ import io.legado.app.lib.webdav.ObjectNotFoundException
import io.legado.app.model.AudioPlay import io.legado.app.model.AudioPlay
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.model.ReadManga
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
@@ -483,6 +484,9 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
if (ReadBook.book?.bookUrl == bookData.value!!.bookUrl) { if (ReadBook.book?.bookUrl == bookData.value!!.bookUrl) {
ReadBook.clearTextChapter() ReadBook.clearTextChapter()
} }
if (ReadManga.book?.bookUrl == bookData.value!!.bookUrl) {
ReadManga.clearMangaChapter()
}
}.onSuccess { }.onSuccess {
context.toastOnUi(R.string.clear_cache_success) context.toastOnUi(R.string.clear_cache_success)
}.onError { }.onError {
@@ -15,7 +15,6 @@ import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocal
import io.legado.app.help.book.isLocalModified import io.legado.app.help.book.isLocalModified
import io.legado.app.help.book.removeType import io.legado.app.help.book.removeType
import io.legado.app.help.book.simulatedTotalChapterNum
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.ReadManga import io.legado.app.model.ReadManga
@@ -81,7 +80,6 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
if ((ReadManga.chapterSize == 0 || book.isLocalModified()) && !loadChapterListAwait(book)) { if ((ReadManga.chapterSize == 0 || book.isLocalModified()) && !loadChapterListAwait(book)) {
return return
} }
ensureChapterExist()
//开始加载内容 //开始加载内容
if (!isSameBook) { if (!isSameBook) {
@@ -110,8 +108,7 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
} }
appDb.bookChapterDao.delByBook(oldBook.bookUrl) appDb.bookChapterDao.delByBook(oldBook.bookUrl)
appDb.bookChapterDao.insert(*cList.toTypedArray()) appDb.bookChapterDao.insert(*cList.toTypedArray())
ReadManga.chapterSize = cList.size ReadManga.onChapterListUpdated(book)
ReadManga.simulatedChapterSize = book.simulatedTotalChapterNum()
return true return true
}.onFailure { }.onFailure {
//加载章节出错 //加载章节出错
@@ -139,12 +136,6 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
} }
} }
private fun ensureChapterExist() {
if (ReadManga.simulatedChapterSize > 0 && ReadManga.durChapterIndex > ReadManga.simulatedChapterSize - 1) {
ReadManga.durChapterIndex = ReadManga.simulatedChapterSize - 1
}
}
/** /**
* 自动换源 * 自动换源
*/ */
@@ -9,7 +9,6 @@ import android.widget.EditText
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import io.legado.app.R import io.legado.app.R
@@ -39,6 +38,7 @@ import io.legado.app.ui.qrcode.QrCodeResult
import io.legado.app.ui.widget.dialog.UrlOptionDialog import io.legado.app.ui.widget.dialog.UrlOptionDialog
import io.legado.app.ui.widget.dialog.VariableDialog import io.legado.app.ui.widget.dialog.VariableDialog
import io.legado.app.ui.widget.keyboard.KeyboardToolPop import io.legado.app.ui.widget.keyboard.KeyboardToolPop
import io.legado.app.ui.widget.recycler.NoChildScrollLinearLayoutManager
import io.legado.app.ui.widget.text.EditEntity import io.legado.app.ui.widget.text.EditEntity
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.imeHeight import io.legado.app.utils.imeHeight
@@ -184,7 +184,7 @@ class BookSourceEditActivity :
setText(R.string.source_tab_content) setText(R.string.source_tab_content)
}) })
binding.recyclerView.setEdgeEffectColor(primaryColor) binding.recyclerView.setEdgeEffectColor(primaryColor)
binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.layoutManager = NoChildScrollLinearLayoutManager(this)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
binding.tabLayout.setBackgroundColor(backgroundColor) binding.tabLayout.setBackgroundColor(backgroundColor)
binding.tabLayout.setSelectedTabIndicatorColor(accentColor) binding.tabLayout.setSelectedTabIndicatorColor(accentColor)
@@ -0,0 +1,26 @@
package io.legado.app.ui.widget
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import androidx.core.widget.NestedScrollView
class NoChildScrollNestedScrollView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) : NestedScrollView(context, attrs) {
override fun requestChildFocus(child: View?, focused: View?) {
// do nothing
}
override fun requestChildRectangleOnScreen(
child: View,
rectangle: Rect?,
immediate: Boolean
): Boolean {
return false
}
}
@@ -0,0 +1,39 @@
package io.legado.app.ui.widget.recycler
import android.content.Context
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class NoChildScrollLinearLayoutManager(context: Context) : LinearLayoutManager(context) {
override fun onRequestChildFocus(
parent: RecyclerView,
state: RecyclerView.State,
child: View,
focused: View?
): Boolean {
return true
}
override fun requestChildRectangleOnScreen(
parent: RecyclerView,
child: View,
rect: Rect,
immediate: Boolean,
focusedChildVisible: Boolean
): Boolean {
return false
}
override fun requestChildRectangleOnScreen(
parent: RecyclerView,
child: View,
rect: Rect,
immediate: Boolean
): Boolean {
return false
}
}
@@ -35,7 +35,7 @@
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1"> android:layout_weight="1">
<androidx.core.widget.NestedScrollView <io.legado.app.ui.widget.NoChildScrollNestedScrollView
android:id="@+id/scroll_view" android:id="@+id/scroll_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
@@ -374,7 +374,7 @@
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </io.legado.app.ui.widget.NoChildScrollNestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
@@ -15,7 +15,7 @@
app:displayHomeAsUp="true" app:displayHomeAsUp="true"
app:title="@string/replace_rule_edit" /> app:title="@string/replace_rule_edit" />
<androidx.core.widget.NestedScrollView <io.legado.app.ui.widget.NoChildScrollNestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@@ -166,6 +166,6 @@
</io.legado.app.ui.widget.text.TextInputLayout> </io.legado.app.ui.widget.text.TextInputLayout>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </io.legado.app.ui.widget.NoChildScrollNestedScrollView>
</LinearLayout> </LinearLayout>
@@ -36,7 +36,7 @@
app:layout_constraintTop_toBottomOf="@+id/title_bar" app:layout_constraintTop_toBottomOf="@+id/title_bar"
app:loading_width="2dp" /> app:loading_width="2dp" />
<androidx.core.widget.NestedScrollView <io.legado.app.ui.widget.NoChildScrollNestedScrollView
android:id="@+id/help" android:id="@+id/help"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -202,6 +202,6 @@
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </io.legado.app.ui.widget.NoChildScrollNestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>