Horis 1 gadu atpakaļ
vecāks
revīzija
d447ef69ff

+ 16 - 11
app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt

@@ -1,6 +1,5 @@
 package io.legado.app.help.glide
 package io.legado.app.help.glide
 
 
-import android.net.Uri
 import com.bumptech.glide.Priority
 import com.bumptech.glide.Priority
 import com.bumptech.glide.load.DataSource
 import com.bumptech.glide.load.DataSource
 import com.bumptech.glide.load.HttpException
 import com.bumptech.glide.load.HttpException
@@ -8,14 +7,14 @@ import com.bumptech.glide.load.Options
 import com.bumptech.glide.load.data.DataFetcher
 import com.bumptech.glide.load.data.DataFetcher
 import com.bumptech.glide.load.model.GlideUrl
 import com.bumptech.glide.load.model.GlideUrl
 import com.bumptech.glide.util.ContentLengthInputStream
 import com.bumptech.glide.util.ContentLengthInputStream
-import com.bumptech.glide.util.Preconditions
 import io.legado.app.data.entities.BaseSource
 import io.legado.app.data.entities.BaseSource
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.http.CookieManager.cookieJarHeader
 import io.legado.app.help.http.CookieManager.cookieJarHeader
 import io.legado.app.help.http.addHeaders
 import io.legado.app.help.http.addHeaders
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.okHttpClient
+import io.legado.app.help.http.okHttpClientManga
 import io.legado.app.help.source.SourceHelp
 import io.legado.app.help.source.SourceHelp
-import io.legado.app.model.ReadMange
+import io.legado.app.model.ReadManga
 import io.legado.app.utils.ImageUtils
 import io.legado.app.utils.ImageUtils
 import io.legado.app.utils.isWifiConnect
 import io.legado.app.utils.isWifiConnect
 import okhttp3.Call
 import okhttp3.Call
@@ -38,6 +37,7 @@ class OkHttpStreamFetcher(
     private var responseBody: ResponseBody? = null
     private var responseBody: ResponseBody? = null
     private var callback: DataFetcher.DataCallback<in InputStream>? = null
     private var callback: DataFetcher.DataCallback<in InputStream>? = null
     private var source: BaseSource? = null
     private var source: BaseSource? = null
+    private val manga = options.get(OkHttpModelLoader.mangaOption) == true
 
 
     @Volatile
     @Volatile
     private var call: Call? = null
     private var call: Call? = null
@@ -71,7 +71,11 @@ class OkHttpStreamFetcher(
         requestBuilder.addHeaders(headerMap)
         requestBuilder.addHeaders(headerMap)
         val request: Request = requestBuilder.build()
         val request: Request = requestBuilder.build()
         this.callback = callback
         this.callback = callback
-        call = okHttpClient.newCall(request)
+        call = if (manga) {
+            okHttpClientManga.newCall(request)
+        } else {
+            okHttpClient.newCall(request)
+        }
         call?.enqueue(this)
         call?.enqueue(this)
     }
     }
 
 
@@ -102,14 +106,13 @@ class OkHttpStreamFetcher(
     override fun onResponse(call: Call, response: Response) {
     override fun onResponse(call: Call, response: Response) {
         responseBody = response.body
         responseBody = response.body
         if (response.isSuccessful) {
         if (response.isSuccessful) {
-            val manga = options.get(OkHttpModelLoader.mangaOption) == true
             val decodeResult = if (manga) {
             val decodeResult = if (manga) {
                 ImageUtils.decode(
                 ImageUtils.decode(
-                    Uri.decode(oldUrl.toStringUrl()),
-                    responseBody!!.byteStream().readBytes(),
+                    oldUrl.toString(),
+                    responseBody!!.bytes(),
                     isCover = false,
                     isCover = false,
                     source,
                     source,
-                    ReadMange.book
+                    ReadManga.book
                 )?.let {
                 )?.let {
                     ByteArrayInputStream(it)
                     ByteArrayInputStream(it)
                 }
                 }
@@ -123,13 +126,15 @@ class OkHttpStreamFetcher(
                 callback?.onLoadFailed(NoStackTraceException("封面二次解密失败"))
                 callback?.onLoadFailed(NoStackTraceException("封面二次解密失败"))
             } else {
             } else {
                 val contentLength: Long =
                 val contentLength: Long =
-                    if (decodeResult is ByteArrayInputStream) decodeResult.available()
-                        .toLong() else Preconditions.checkNotNull(responseBody).contentLength()
+                    if (decodeResult is ByteArrayInputStream) decodeResult.available().toLong()
+                    else responseBody!!.contentLength()
                 stream = ContentLengthInputStream.obtain(decodeResult, contentLength)
                 stream = ContentLengthInputStream.obtain(decodeResult, contentLength)
                 callback?.onDataReady(stream)
                 callback?.onDataReady(stream)
             }
             }
         } else {
         } else {
-            failUrl.add(url.toStringUrl())
+            if (!manga) {
+                failUrl.add(url.toStringUrl())
+            }
             callback?.onLoadFailed(HttpException(response.message, response.code))
             callback?.onLoadFailed(HttpException(response.message, response.code))
         }
         }
     }
     }

+ 20 - 6
app/src/main/java/io/legado/app/help/glide/progress/ProgressManager.kt

@@ -1,6 +1,6 @@
 package io.legado.app.help.glide.progress
 package io.legado.app.help.glide.progress
 
 
-import android.text.TextUtils
+import io.legado.app.model.analyzeRule.AnalyzeUrl
 import io.legado.app.utils.runOnUI
 import io.legado.app.utils.runOnUI
 import java.util.concurrent.ConcurrentHashMap
 import java.util.concurrent.ConcurrentHashMap
 
 
@@ -31,21 +31,35 @@ object ProgressManager {
     }
     }
 
 
     fun addListener(url: String, listener: OnProgressListener) {
     fun addListener(url: String, listener: OnProgressListener) {
-        if (!TextUtils.isEmpty(url) && listener != null) {
+        if (url.isNotEmpty() && listener != null) {
+            val url = getUrlNoOption(url)
             listenersMap[url] = listener
             listenersMap[url] = listener
             listener.invoke(false, 1, 0, 0)
             listener.invoke(false, 1, 0, 0)
         }
         }
     }
     }
 
 
     fun removeListener(url: String) {
     fun removeListener(url: String) {
-        if (!TextUtils.isEmpty(url)) {
+        if (url.isNotEmpty()) {
+            val url = getUrlNoOption(url)
             listenersMap.remove(url)
             listenersMap.remove(url)
         }
         }
     }
     }
 
 
-    fun getProgressListener(url: String?): OnProgressListener {
-        return if (TextUtils.isEmpty(url) || listenersMap.size == 0) {
+    fun getProgressListener(url: String): OnProgressListener {
+        return if (url.isEmpty() || listenersMap.isEmpty()) {
             null
             null
-        } else listenersMap[url]
+        } else {
+            listenersMap[url]
+        }
     }
     }
+
+    private fun getUrlNoOption(url: String): String {
+        val urlMatcher = AnalyzeUrl.paramPattern.matcher(url)
+        return if (urlMatcher.find()) {
+            url.substring(0, urlMatcher.start())
+        } else {
+            url
+        }
+    }
+
 }
 }

+ 22 - 10
app/src/main/java/io/legado/app/help/http/HttpHelper.kt

@@ -3,10 +3,10 @@ package io.legado.app.help.http
 import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppConst
 import io.legado.app.help.CacheManager
 import io.legado.app.help.CacheManager
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
-import io.legado.app.help.glide.progress.ProgressManager
 import io.legado.app.help.glide.progress.ProgressManager.LISTENER
 import io.legado.app.help.glide.progress.ProgressManager.LISTENER
 import io.legado.app.help.glide.progress.ProgressResponseBody
 import io.legado.app.help.glide.progress.ProgressResponseBody
 import io.legado.app.help.http.CookieManager.cookieJarHeader
 import io.legado.app.help.http.CookieManager.cookieJarHeader
+import io.legado.app.model.ReadManga
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.NetworkUtils
 import okhttp3.ConnectionSpec
 import okhttp3.ConnectionSpec
 import okhttp3.Cookie
 import okhttp3.Cookie
@@ -96,15 +96,7 @@ val okHttpClient: OkHttpClient by lazy {
             if (enableCookieJar) {
             if (enableCookieJar) {
                 CookieManager.saveResponse(networkResponse)
                 CookieManager.saveResponse(networkResponse)
             }
             }
-            networkResponse.newBuilder()
-                .body(
-                    ProgressResponseBody(
-                        request.url.toString(),
-                        LISTENER,
-                        networkResponse.body!!
-                    )
-                )
-                .build()
+            networkResponse
         }
         }
     if (AppConfig.isCronet) {
     if (AppConfig.isCronet) {
         if (Cronet.loader?.install() == true) {
         if (Cronet.loader?.install() == true) {
@@ -128,6 +120,26 @@ val okHttpClient: OkHttpClient by lazy {
     }
     }
 }
 }
 
 
+val okHttpClientManga by lazy {
+    okHttpClient.newBuilder().run {
+        val interceptors = interceptors()
+        interceptors.add(1) { chain ->
+            val request = chain.request()
+            val response = chain.proceed(request)
+            val url = request.url.toString()
+            response.newBuilder()
+                .body(ProgressResponseBody(url, LISTENER, response.body!!))
+                .build()
+        }
+        interceptors.add(1) { chain ->
+            ReadManga.rateLimiter.withLimitBlocking {
+                chain.proceed(chain.request())
+            }
+        }
+        build()
+    }
+}
+
 /**
 /**
  * 缓存代理okHttp
  * 缓存代理okHttp
  */
  */

+ 0 - 1
app/src/main/java/io/legado/app/model/BookCover.kt

@@ -97,7 +97,6 @@ object BookCover {
     /**
     /**
      * 加载漫画图片
      * 加载漫画图片
      */
      */
-
     fun loadManga(
     fun loadManga(
         context: Context,
         context: Context,
         path: String?,
         path: String?,

+ 13 - 11
app/src/main/java/io/legado/app/model/ReadMange.kt → app/src/main/java/io/legado/app/model/ReadManga.kt

@@ -9,6 +9,7 @@ import io.legado.app.data.entities.BookProgress
 import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.ReadRecord
 import io.legado.app.data.entities.ReadRecord
 import io.legado.app.help.AppWebDav
 import io.legado.app.help.AppWebDav
+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
@@ -41,7 +42,7 @@ import kotlinx.coroutines.launch
 import kotlin.math.min
 import kotlin.math.min
 
 
 @Suppress("MemberVisibilityCanBePrivate")
 @Suppress("MemberVisibilityCanBePrivate")
-object ReadMange : CoroutineScope by MainScope() {
+object ReadManga : CoroutineScope by MainScope() {
     var inBookshelf = false
     var inBookshelf = false
     var tocChanged = false
     var tocChanged = false
     var chapterChanged = false
     var chapterChanged = false
@@ -67,10 +68,11 @@ object ReadMange : CoroutineScope by MainScope() {
     private val downloadLoadingChapters = arrayListOf<Int>()
     private val downloadLoadingChapters = arrayListOf<Int>()
     var isMangaMode = false
     var isMangaMode = false
     val downloadScope = CoroutineScope(SupervisorJob() + IO)
     val downloadScope = CoroutineScope(SupervisorJob() + IO)
+    var rateLimiter = ConcurrentRateLimiter(null)
 
 
     fun saveRead(pageChanged: Boolean = false) {
     fun saveRead(pageChanged: Boolean = false) {
         executor.execute {
         executor.execute {
-            val book = ReadMange.book ?: return@execute
+            val book = ReadManga.book ?: return@execute
             book.lastCheckCount = 0
             book.lastCheckCount = 0
             book.durChapterTime = System.currentTimeMillis()
             book.durChapterTime = System.currentTimeMillis()
             val chapterChanged = book.durChapterIndex != durChapterPagePos
             val chapterChanged = book.durChapterIndex != durChapterPagePos
@@ -89,7 +91,7 @@ object ReadMange : CoroutineScope by MainScope() {
     }
     }
 
 
     fun upData(book: Book) {
     fun upData(book: Book) {
-        ReadMange.book = book
+        ReadManga.book = book
         isMangaMode = true
         isMangaMode = true
         durChapterPageCount = appDb.bookChapterDao.getChapterCount(book.bookUrl)
         durChapterPageCount = appDb.bookChapterDao.getChapterCount(book.bookUrl)
         simulatedChapterSize = if (book.readSimulating()) {
         simulatedChapterSize = if (book.readSimulating()) {
@@ -103,14 +105,13 @@ object ReadMange : CoroutineScope by MainScope() {
             durChapterPos = book.durChapterPos
             durChapterPos = book.durChapterPos
         }
         }
         upWebBook(book)
         upWebBook(book)
-
         synchronized(this) {
         synchronized(this) {
             loadingChapters.clear()
             loadingChapters.clear()
         }
         }
     }
     }
 
 
     fun resetData(book: Book) {
     fun resetData(book: Book) {
-        ReadMange.book = book
+        ReadManga.book = book
         isMangaMode = true
         isMangaMode = true
         readRecord.bookName = book.name
         readRecord.bookName = book.name
         readRecord.readTime = appDb.readRecordDao.getReadTime(book.name) ?: 0
         readRecord.readTime = appDb.readRecordDao.getReadTime(book.name) ?: 0
@@ -131,6 +132,7 @@ object ReadMange : CoroutineScope by MainScope() {
     fun upWebBook(book: Book) {
     fun upWebBook(book: Book) {
         appDb.bookSourceDao.getBookSource(book.origin)?.let {
         appDb.bookSourceDao.getBookSource(book.origin)?.let {
             bookSource = it
             bookSource = it
+            rateLimiter = ConcurrentRateLimiter(it)
         } ?: let {
         } ?: let {
             bookSource = null
             bookSource = null
         }
         }
@@ -193,8 +195,8 @@ object ReadMange : CoroutineScope by MainScope() {
         scope: CoroutineScope,
         scope: CoroutineScope,
         chapter: BookChapter,
         chapter: BookChapter,
     ) {
     ) {
-        val book = ReadMange.book ?: return removeLoading(chapter.index)
-        val bookSource = ReadMange.bookSource
+        val book = ReadManga.book ?: return removeLoading(chapter.index)
+        val bookSource = ReadManga.bookSource
         if (bookSource != null) {
         if (bookSource != null) {
             getContent(bookSource, scope, chapter, book)
             getContent(bookSource, scope, chapter, book)
         }
         }
@@ -210,7 +212,7 @@ object ReadMange : CoroutineScope by MainScope() {
     ) {
     ) {
         if (addLoading(index)) {
         if (addLoading(index)) {
             Coroutine.async {
             Coroutine.async {
-                val book = ReadMange.book!!
+                val book = ReadManga.book!!
                 appDb.bookChapterDao.getChapter(book.bookUrl, index)?.let { chapter ->
                 appDb.bookChapterDao.getChapter(book.bookUrl, index)?.let { chapter ->
                     getContent(
                     getContent(
                         downloadScope,
                         downloadScope,
@@ -368,7 +370,7 @@ object ReadMange : CoroutineScope by MainScope() {
         if (System.currentTimeMillis() - book.lastCheckTime < 600000) return
         if (System.currentTimeMillis() - book.lastCheckTime < 600000) return
         book.lastCheckTime = System.currentTimeMillis()
         book.lastCheckTime = System.currentTimeMillis()
         WebBook.getChapterList(this, bookSource, book).onSuccess(IO) { cList ->
         WebBook.getChapterList(this, bookSource, book).onSuccess(IO) { cList ->
-            if (book.bookUrl == ReadMange.book?.bookUrl
+            if (book.bookUrl == ReadManga.book?.bookUrl
                 && cList.size > durChapterPageCount
                 && cList.size > durChapterPageCount
             ) {
             ) {
                 appDb.bookChapterDao.delByBook(book.bookUrl)
                 appDb.bookChapterDao.delByBook(book.bookUrl)
@@ -532,7 +534,7 @@ object ReadMange : CoroutineScope by MainScope() {
         if (System.currentTimeMillis() - book.lastCheckTime < 600000) return
         if (System.currentTimeMillis() - book.lastCheckTime < 600000) return
         book.lastCheckTime = System.currentTimeMillis()
         book.lastCheckTime = System.currentTimeMillis()
         WebBook.getChapterList(this, bookSource, book).onSuccess(IO) { cList ->
         WebBook.getChapterList(this, bookSource, book).onSuccess(IO) { cList ->
-            if (book.bookUrl == ReadMange.book?.bookUrl
+            if (book.bookUrl == ReadManga.book?.bookUrl
                 && cList.size > durChapterPageCount
                 && cList.size > durChapterPageCount
             ) {
             ) {
                 appDb.bookChapterDao.delByBook(book.bookUrl)
                 appDb.bookChapterDao.delByBook(book.bookUrl)
@@ -609,7 +611,7 @@ object ReadMange : CoroutineScope by MainScope() {
                     loadContent(durChapterPagePos)
                     loadContent(durChapterPagePos)
                 } else {
                 } else {
                     Coroutine.async {
                     Coroutine.async {
-                        val book = ReadMange.book!!
+                        val book = ReadManga.book!!
                         appDb.bookChapterDao.getChapter(book.bookUrl, durChapterPagePos)
                         appDb.bookChapterDao.getChapter(book.bookUrl, durChapterPagePos)
                             ?.let { chapter ->
                             ?.let { chapter ->
                                 getContent(
                                 getContent(

+ 2 - 2
app/src/main/java/io/legado/app/model/recyclerView/MangaVH.kt

@@ -24,7 +24,7 @@ import io.legado.app.R
 import io.legado.app.help.glide.progress.OnProgressListener
 import io.legado.app.help.glide.progress.OnProgressListener
 import io.legado.app.help.glide.progress.ProgressManager
 import io.legado.app.help.glide.progress.ProgressManager
 import io.legado.app.model.BookCover
 import io.legado.app.model.BookCover
-import io.legado.app.model.ReadMange
+import io.legado.app.model.ReadManga
 import io.legado.app.utils.getCompatDrawable
 import io.legado.app.utils.getCompatDrawable
 import io.legado.app.utils.printOnDebug
 import io.legado.app.utils.printOnDebug
 
 
@@ -74,7 +74,7 @@ open class MangaVH<VB : ViewBinding>(val binding: VB, private val context: Conte
             BookCover.loadManga(
             BookCover.loadManga(
                 context,
                 context,
                 imageUrl,
                 imageUrl,
-                sourceOrigin = ReadMange.book?.origin,
+                sourceOrigin = ReadManga.book?.origin,
                 manga = true,
                 manga = true,
                 useDefaultCover = context.getCompatDrawable(R.color.book_ant_10)
                 useDefaultCover = context.getCompatDrawable(R.color.book_ant_10)
             ).addListener(object : RequestListener<Drawable> {
             ).addListener(object : RequestListener<Drawable> {

+ 30 - 30
app/src/main/java/io/legado/app/ui/book/manga/MangaViewModel.kt

@@ -18,7 +18,7 @@ import io.legado.app.help.book.removeType
 import io.legado.app.help.book.simulatedTotalChapterNum
 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.ReadMange
+import io.legado.app.model.ReadManga
 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
 import io.legado.app.utils.mapParallelSafe
 import io.legado.app.utils.mapParallelSafe
@@ -42,13 +42,13 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
      */
      */
     fun initData(intent: Intent, success: (() -> Unit)? = null) {
     fun initData(intent: Intent, success: (() -> Unit)? = null) {
         execute {
         execute {
-            ReadMange.inBookshelf = intent.getBooleanExtra("inBookshelf", true)
-            ReadMange.tocChanged = intent.getBooleanExtra("tocChanged", false)
+            ReadManga.inBookshelf = intent.getBooleanExtra("inBookshelf", true)
+            ReadManga.tocChanged = intent.getBooleanExtra("tocChanged", false)
             val bookUrl = intent.getStringExtra("bookUrl")
             val bookUrl = intent.getStringExtra("bookUrl")
             val book = when {
             val book = when {
                 bookUrl.isNullOrEmpty() -> appDb.bookDao.lastReadBook
                 bookUrl.isNullOrEmpty() -> appDb.bookDao.lastReadBook
                 else -> appDb.bookDao.getBook(bookUrl)
                 else -> appDb.bookDao.getBook(bookUrl)
-            } ?: ReadMange.book
+            } ?: ReadManga.book
             when {
             when {
                 book != null -> initMange(book)
                 book != null -> initMange(book)
                 else -> context.getString(R.string.no_book)//没有找到书
                 else -> context.getString(R.string.no_book)//没有找到书
@@ -59,16 +59,16 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
             val msg = "初始化数据失败\n${it.localizedMessage}"
             val msg = "初始化数据失败\n${it.localizedMessage}"
             AppLog.put(msg, it)
             AppLog.put(msg, it)
         }.onFinally {
         }.onFinally {
-            ReadMange.saveRead()
+            ReadManga.saveRead()
         }
         }
     }
     }
 
 
     private suspend fun initMange(book: Book) {
     private suspend fun initMange(book: Book) {
-        val isSameBook = ReadMange.book?.bookUrl == book.bookUrl
+        val isSameBook = ReadManga.book?.bookUrl == book.bookUrl
         if (isSameBook) {
         if (isSameBook) {
-            ReadMange.upData(book)
+            ReadManga.upData(book)
         } else {
         } else {
-            ReadMange.resetData(book)
+            ReadManga.resetData(book)
         }
         }
         if (!book.isLocal && book.tocUrl.isEmpty() && !loadBookInfo(book)) {
         if (!book.isLocal && book.tocUrl.isEmpty() && !loadBookInfo(book)) {
             return
             return
@@ -78,7 +78,7 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
             return
             return
         }
         }
 
 
-        if ((ReadMange.durChapterPageCount == 0 || book.isLocalModified()) && !loadChapterListAwait(
+        if ((ReadManga.durChapterPageCount == 0 || book.isLocalModified()) && !loadChapterListAwait(
                 book
                 book
             )
             )
         ) {
         ) {
@@ -87,17 +87,17 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
         ensureChapterExist()
         ensureChapterExist()
 
 
         //开始加载内容
         //开始加载内容
-        ReadMange.loadContent()
+        ReadManga.loadContent()
 
 
         //自动换源
         //自动换源
-        if (!book.isLocal && ReadMange.bookSource == null) {
+        if (!book.isLocal && ReadManga.bookSource == null) {
             autoChangeSource(book.name, book.author)
             autoChangeSource(book.name, book.author)
             return
             return
         }
         }
     }
     }
 
 
     private suspend fun loadChapterListAwait(book: Book): Boolean {
     private suspend fun loadChapterListAwait(book: Book): Boolean {
-        ReadMange.bookSource?.let {
+        ReadManga.bookSource?.let {
             val oldBook = book.copy()
             val oldBook = book.copy()
             WebBook.getChapterListAwait(it, book, true).onSuccess { cList ->
             WebBook.getChapterListAwait(it, book, true).onSuccess { cList ->
                 if (oldBook.bookUrl == book.bookUrl) {
                 if (oldBook.bookUrl == book.bookUrl) {
@@ -108,12 +108,12 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
                 }
                 }
                 appDb.bookChapterDao.delByBook(oldBook.bookUrl)
                 appDb.bookChapterDao.delByBook(oldBook.bookUrl)
                 appDb.bookChapterDao.insert(*cList.toTypedArray())
                 appDb.bookChapterDao.insert(*cList.toTypedArray())
-                ReadMange.durChapterPageCount = cList.size
-                ReadMange.simulatedChapterSize = book.simulatedTotalChapterNum()
+                ReadManga.durChapterPageCount = cList.size
+                ReadManga.simulatedChapterSize = book.simulatedTotalChapterNum()
                 return true
                 return true
             }.onFailure {
             }.onFailure {
                 //加载章节出错
                 //加载章节出错
-                ReadMange.mCallback?.loadFail("加载目录失败")
+                ReadManga.mCallback?.loadFail("加载目录失败")
                 return false
                 return false
             }
             }
         }
         }
@@ -126,7 +126,7 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
      * 加载详情页
      * 加载详情页
      */
      */
     private suspend fun loadBookInfo(book: Book): Boolean {
     private suspend fun loadBookInfo(book: Book): Boolean {
-        val source = ReadMange.bookSource ?: return true
+        val source = ReadManga.bookSource ?: return true
         try {
         try {
             WebBook.getBookInfoAwait(source, book, canReName = false)
             WebBook.getBookInfoAwait(source, book, canReName = false)
             return true
             return true
@@ -138,8 +138,8 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
     }
     }
 
 
     private fun ensureChapterExist() {
     private fun ensureChapterExist() {
-        if (ReadMange.simulatedChapterSize > 0 && ReadMange.durChapterPagePos > ReadMange.simulatedChapterSize - 1) {
-            ReadMange.durChapterPagePos = ReadMange.simulatedChapterSize - 1
+        if (ReadManga.simulatedChapterSize > 0 && ReadManga.durChapterPagePos > ReadManga.simulatedChapterSize - 1) {
+            ReadManga.durChapterPagePos = ReadManga.simulatedChapterSize - 1
         }
         }
     }
     }
 
 
@@ -198,15 +198,15 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
         changeSourceCoroutine?.cancel()
         changeSourceCoroutine?.cancel()
         changeSourceCoroutine = execute {
         changeSourceCoroutine = execute {
             //换源中
             //换源中
-            ReadMange.book?.migrateTo(book, toc)
+            ReadManga.book?.migrateTo(book, toc)
             book.removeType(BookType.updateError)
             book.removeType(BookType.updateError)
-            ReadMange.book?.delete()
+            ReadManga.book?.delete()
             appDb.bookDao.insert(book)
             appDb.bookDao.insert(book)
             appDb.bookChapterDao.insert(*toc.toTypedArray())
             appDb.bookChapterDao.insert(*toc.toTypedArray())
-            ReadMange.resetData(book)
-            toc.find { it.title.contains(ReadMange.chapterTitle) }?.run {
-                ReadMange.loadContent(index)
-            } ?: ReadMange.loadContent()
+            ReadManga.resetData(book)
+            toc.find { it.title.contains(ReadManga.chapterTitle) }?.run {
+                ReadManga.loadContent(index)
+            } ?: ReadManga.loadContent()
         }.onError {
         }.onError {
             AppLog.put("换源失败\n$it", it, true)
             AppLog.put("换源失败\n$it", it, true)
         }.onFinally {
         }.onFinally {
@@ -224,12 +224,12 @@ class MangaViewModel(application: Application) : BaseViewModel(application) {
     }
     }
 
 
     fun openChapter(index: Int, durChapterPos: Int = 0) {
     fun openChapter(index: Int, durChapterPos: Int = 0) {
-        if (index < ReadMange.durChapterPageCount) {
-            ReadMange.chapterChanged = true
-            ReadMange.durChapterPagePos = index
-            ReadMange.durChapterPos = durChapterPos
-            ReadMange.saveRead()
-            ReadMange.loadContent(index)
+        if (index < ReadManga.durChapterPageCount) {
+            ReadManga.chapterChanged = true
+            ReadManga.durChapterPagePos = index
+            ReadManga.durChapterPos = durChapterPos
+            ReadManga.saveRead()
+            ReadManga.loadContent(index)
         }
         }
     }
     }
 
 

+ 34 - 34
app/src/main/java/io/legado/app/ui/book/manga/ReadMangaActivity.kt

@@ -31,8 +31,8 @@ import io.legado.app.help.book.isImage
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.storage.Backup
 import io.legado.app.help.storage.Backup
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
-import io.legado.app.model.ReadMange
-import io.legado.app.model.ReadMange.mFirstLoading
+import io.legado.app.model.ReadManga
+import io.legado.app.model.ReadManga.mFirstLoading
 import io.legado.app.model.recyclerView.MangeContent
 import io.legado.app.model.recyclerView.MangeContent
 import io.legado.app.model.recyclerView.ReaderLoading
 import io.legado.app.model.recyclerView.ReaderLoading
 import io.legado.app.receiver.NetworkChangedListener
 import io.legado.app.receiver.NetworkChangedListener
@@ -56,7 +56,7 @@ import io.legado.app.utils.visible
 import splitties.dimensions.dp
 import splitties.dimensions.dp
 
 
 class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>(),
 class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>(),
-    ReadMange.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack {
+    ReadManga.Callback, ChangeBookSourceDialog.CallBack, MangaMenu.CallBack {
 
 
     private val mLayoutManager by lazy {
     private val mLayoutManager by lazy {
         LinearLayoutManager(this@ReadMangaActivity)
         LinearLayoutManager(this@ReadMangaActivity)
@@ -114,7 +114,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
 
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
     override fun onActivityCreated(savedInstanceState: Bundle?) {
         immersionFullScreen(windowInsetsControllerCompat)
         immersionFullScreen(windowInsetsControllerCompat)
-        ReadMange.register(this)
+        ReadManga.register(this)
         binding.mRecyclerMange.run {
         binding.mRecyclerMange.run {
             adapter = mAdapter
             adapter = mAdapter
             itemAnimator = null
             itemAnimator = null
@@ -141,7 +141,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
                     try {
                     try {
                         val content = mAdapter.getCurrentList()[position]
                         val content = mAdapter.getCurrentList()[position]
                         if (content is MangeContent) {
                         if (content is MangeContent) {
-                            ReadMange.durChapterPos = content.mDurChapterPos.minus(1)
+                            ReadManga.durChapterPos = content.mDurChapterPos.minus(1)
                             upText(
                             upText(
                                 content.mChapterPagePos,
                                 content.mChapterPagePos,
                                 content.mChapterPageCount,
                                 content.mChapterPageCount,
@@ -166,15 +166,15 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
             binding.llLoading.isVisible = true
             binding.llLoading.isVisible = true
             binding.llRetry.isGone = true
             binding.llRetry.isGone = true
             mFirstLoading = false
             mFirstLoading = false
-            ReadMange.loadContent()
+            ReadManga.loadContent()
         }
         }
 
 
         mAdapter.addFooterView {
         mAdapter.addFooterView {
             ViewLoadMoreBinding.bind(loadMoreView)
             ViewLoadMoreBinding.bind(loadMoreView)
         }
         }
         loadMoreView.setOnClickListener {
         loadMoreView.setOnClickListener {
-            if (!loadMoreView.isLoading && !ReadMange.gameOver) {
-                scrollToBottom(true, ReadMange.durChapterPagePos)
+            if (!loadMoreView.isLoading && !ReadManga.gameOver) {
+                scrollToBottom(true, ReadManga.durChapterPagePos)
             }
             }
         }
         }
         loadMoreView.gone()
         loadMoreView.gone()
@@ -191,9 +191,9 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     }
     }
 
 
     private fun scrollToBottom(forceLoad: Boolean = false, index: Int) {
     private fun scrollToBottom(forceLoad: Boolean = false, index: Int) {
-        if ((loadMoreView.hasMore && !loadMoreView.isLoading) && !ReadMange.gameOver || forceLoad) {
+        if ((loadMoreView.hasMore && !loadMoreView.isLoading) && !ReadManga.gameOver || forceLoad) {
             loadMoreView.hasMore()
             loadMoreView.hasMore()
-            ReadMange.moveToNextChapter(index)
+            ReadManga.moveToNextChapter(index)
         }
         }
     }
     }
 
 
@@ -213,27 +213,27 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
                     if (list.size > 1) {
                     if (list.size > 1) {
                         binding.infobar.isVisible = true
                         binding.infobar.isVisible = true
                         upText(
                         upText(
-                            ReadMange.durChapterPagePos,
-                            ReadMange.durChapterPageCount,
-                            ReadMange.durChapterPos,
-                            ReadMange.durChapterCount
+                            ReadManga.durChapterPagePos,
+                            ReadManga.durChapterPageCount,
+                            ReadManga.durChapterPos,
+                            ReadManga.durChapterCount
                         )
                         )
                     }
                     }
 
 
-                    if (ReadMange.durChapterPos + 2 > mAdapter.getCurrentList().size - 3) {
+                    if (ReadManga.durChapterPos + 2 > mAdapter.getCurrentList().size - 3) {
                         val nextIndex =
                         val nextIndex =
                             (mAdapter.getCurrentList().last() as ReaderLoading).mNextChapterIndex
                             (mAdapter.getCurrentList().last() as ReaderLoading).mNextChapterIndex
                         scrollToBottom(index = nextIndex)
                         scrollToBottom(index = nextIndex)
                     } else {
                     } else {
-                        binding.mRecyclerMange.scrollToPosition(ReadMange.durChapterPos)
+                        binding.mRecyclerMange.scrollToPosition(ReadManga.durChapterPos)
                     }
                     }
                 }
                 }
 
 
-                if (ReadMange.chapterChanged) {
-                    binding.mRecyclerMange.scrollToPosition(ReadMange.durChapterPos)
+                if (ReadManga.chapterChanged) {
+                    binding.mRecyclerMange.scrollToPosition(ReadManga.durChapterPos)
                 }
                 }
 
 
-                ReadMange.chapterChanged = false
+                ReadManga.chapterChanged = false
                 loadMoreView.visible()
                 loadMoreView.visible()
                 mFirstLoading = true
                 mFirstLoading = true
                 loadMoreView.stopLoad()
                 loadMoreView.stopLoad()
@@ -259,20 +259,20 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
         networkChangedListener.onNetworkChanged = {
         networkChangedListener.onNetworkChanged = {
             // 当网络是可用状态且无需初始化时同步进度(初始化中已有同步进度逻辑)
             // 当网络是可用状态且无需初始化时同步进度(初始化中已有同步进度逻辑)
             if (AppConfig.syncBookProgressPlus && NetworkUtils.isAvailable() && !justInitData) {
             if (AppConfig.syncBookProgressPlus && NetworkUtils.isAvailable() && !justInitData) {
-                ReadMange.syncProgress({ progress -> sureNewProgress(progress) })
+                ReadManga.syncProgress({ progress -> sureNewProgress(progress) })
             }
             }
         }
         }
     }
     }
 
 
     override fun onPause() {
     override fun onPause() {
         super.onPause()
         super.onPause()
-        if (ReadMange.inBookshelf) {
-            ReadMange.saveRead()
+        if (ReadManga.inBookshelf) {
+            ReadManga.saveRead()
             if (!BuildConfig.DEBUG) {
             if (!BuildConfig.DEBUG) {
                 if (AppConfig.syncBookProgressPlus) {
                 if (AppConfig.syncBookProgressPlus) {
-                    ReadMange.syncProgress()
+                    ReadManga.syncProgress()
                 } else {
                 } else {
-                    ReadMange.uploadProgress()
+                    ReadManga.uploadProgress()
                 }
                 }
                 Backup.autoBack(this)
                 Backup.autoBack(this)
             }
             }
@@ -285,7 +285,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     }
     }
 
 
     override fun loadFail(msg: String) {
     override fun loadFail(msg: String) {
-        if (!mFirstLoading || ReadMange.chapterChanged) {
+        if (!mFirstLoading || ReadManga.chapterChanged) {
             binding.llLoading.isGone = true
             binding.llLoading.isGone = true
             binding.llRetry.isVisible = true
             binding.llRetry.isVisible = true
             binding.tvMsg.text = msg
             binding.tvMsg.text = msg
@@ -299,8 +299,8 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     }
     }
 
 
     override fun adjustmentProgress() {
     override fun adjustmentProgress() {
-        if (ReadMange.chapterChanged) {
-            binding.mRecyclerMange.scrollToPosition(ReadMange.durChapterPos)
+        if (ReadManga.chapterChanged) {
+            binding.mRecyclerMange.scrollToPosition(ReadManga.durChapterPos)
             binding.flLoading.isGone = true
             binding.flLoading.isGone = true
         }
         }
     }
     }
@@ -309,7 +309,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
         get() = mAdapter.getCurrentList()
         get() = mAdapter.getCurrentList()
 
 
     override fun onDestroy() {
     override fun onDestroy() {
-        ReadMange.unregister()
+        ReadManga.unregister()
         super.onDestroy()
         super.onDestroy()
     }
     }
 
 
@@ -324,19 +324,19 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
             setMessage(R.string.cloud_progress_exceeds_current)
             setMessage(R.string.cloud_progress_exceeds_current)
             okButton {
             okButton {
                 binding.flLoading.isVisible = true
                 binding.flLoading.isVisible = true
-                ReadMange.setProgress(progress)
+                ReadManga.setProgress(progress)
             }
             }
             noButton()
             noButton()
         }
         }
     }
     }
 
 
     override val oldBook: Book?
     override val oldBook: Book?
-        get() = ReadMange.book
+        get() = ReadManga.book
 
 
     override fun changeTo(source: BookSource, book: Book, toc: List<BookChapter>) {
     override fun changeTo(source: BookSource, book: Book, toc: List<BookChapter>) {
         if (book.isImage) {
         if (book.isImage) {
             binding.flLoading.isVisible = true
             binding.flLoading.isVisible = true
-            ReadMange.chapterChanged = true
+            ReadManga.chapterChanged = true
             viewModel.changeTo(book, toc)
             viewModel.changeTo(book, toc)
         } else {
         } else {
             toastOnUi("所选择的源不是漫画源")
             toastOnUi("所选择的源不是漫画源")
@@ -356,13 +356,13 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
         when (item.itemId) {
         when (item.itemId) {
             R.id.menu_change_source -> {
             R.id.menu_change_source -> {
                 binding.mangaMenu.runMenuOut()
                 binding.mangaMenu.runMenuOut()
-                ReadMange.book?.let {
+                ReadManga.book?.let {
                     showDialogFragment(ChangeBookSourceDialog(it.name, it.author))
                     showDialogFragment(ChangeBookSourceDialog(it.name, it.author))
                 }
                 }
             }
             }
 
 
             R.id.menu_catalog -> {
             R.id.menu_catalog -> {
-                ReadMange.book?.let {
+                ReadManga.book?.let {
                     tocActivity.launch(it.bookUrl)
                     tocActivity.launch(it.bookUrl)
                 }
                 }
             }
             }
@@ -371,7 +371,7 @@ class ReadMangaActivity : VMBaseActivity<ActivityMangeBinding, MangaViewModel>()
     }
     }
 
 
     override fun openBookInfoActivity() {
     override fun openBookInfoActivity() {
-        ReadMange.book?.let {
+        ReadManga.book?.let {
             bookInfoActivity.launch {
             bookInfoActivity.launch {
                 putExtra("name", it.name)
                 putExtra("name", it.name)
                 putExtra("author", it.author)
                 putExtra("author", it.author)

+ 3 - 3
app/src/main/java/io/legado/app/ui/book/manga/rv/MangaAdapter.kt

@@ -22,7 +22,7 @@ import io.legado.app.databinding.BookComicLoadingRvBinding
 import io.legado.app.databinding.BookComicRvBinding
 import io.legado.app.databinding.BookComicRvBinding
 import io.legado.app.help.glide.progress.ProgressManager
 import io.legado.app.help.glide.progress.ProgressManager
 import io.legado.app.model.BookCover
 import io.legado.app.model.BookCover
-import io.legado.app.model.ReadMange
+import io.legado.app.model.ReadManga
 import io.legado.app.model.recyclerView.MangaVH
 import io.legado.app.model.recyclerView.MangaVH
 import io.legado.app.model.recyclerView.MangeContent
 import io.legado.app.model.recyclerView.MangeContent
 import io.legado.app.model.recyclerView.ReaderLoading
 import io.legado.app.model.recyclerView.ReaderLoading
@@ -66,7 +66,7 @@ class MangaAdapter(private val context: Context) :
     fun submitList(contents: MutableList<Any>, runnable: Runnable) {
     fun submitList(contents: MutableList<Any>, runnable: Runnable) {
         val currentList = mDiffer.currentList.toMutableList()
         val currentList = mDiffer.currentList.toMutableList()
         currentList.addAll(contents)
         currentList.addAll(contents)
-        if (ReadMange.chapterChanged) {
+        if (ReadManga.chapterChanged) {
             mDiffer.submitList(contents) {
             mDiffer.submitList(contents) {
                 runnable.run()
                 runnable.run()
             }
             }
@@ -220,7 +220,7 @@ class MangaAdapter(private val context: Context) :
             return BookCover.loadManga(
             return BookCover.loadManga(
                 context,
                 context,
                 item.mImageUrl,
                 item.mImageUrl,
-                sourceOrigin = ReadMange.book?.origin,
+                sourceOrigin = ReadManga.book?.origin,
                 manga = true,
                 manga = true,
                 useDefaultCover = context.getCompatDrawable(R.color.book_ant_10)
                 useDefaultCover = context.getCompatDrawable(R.color.book_ant_10)
             )
             )

+ 3 - 5
app/src/main/java/io/legado/app/ui/book/read/MangaMenu.kt

@@ -6,8 +6,6 @@ import android.graphics.Color
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.GradientDrawable
 import android.util.AttributeSet
 import android.util.AttributeSet
 import android.view.LayoutInflater
 import android.view.LayoutInflater
-import android.view.View.OnClickListener
-import android.view.View.OnLongClickListener
 import android.view.animation.Animation
 import android.view.animation.Animation
 import android.widget.FrameLayout
 import android.widget.FrameLayout
 import androidx.core.view.isGone
 import androidx.core.view.isGone
@@ -22,7 +20,7 @@ import io.legado.app.lib.theme.bottomBackground
 import io.legado.app.lib.theme.getPrimaryTextColor
 import io.legado.app.lib.theme.getPrimaryTextColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryTextColor
 import io.legado.app.lib.theme.primaryTextColor
-import io.legado.app.model.ReadMange
+import io.legado.app.model.ReadManga
 import io.legado.app.ui.browser.WebViewActivity
 import io.legado.app.ui.browser.WebViewActivity
 import io.legado.app.utils.ColorUtils
 import io.legado.app.utils.ColorUtils
 import io.legado.app.utils.ConstraintModify
 import io.legado.app.utils.ConstraintModify
@@ -95,7 +93,7 @@ class MangaMenu @JvmOverloads constructor(
     private val menuInListener = object : Animation.AnimationListener {
     private val menuInListener = object : Animation.AnimationListener {
         override fun onAnimationStart(animation: Animation) {
         override fun onAnimationStart(animation: Animation) {
             binding.tvSourceAction.text =
             binding.tvSourceAction.text =
-                ReadMange.bookSource?.bookSourceName ?: context.getString(R.string.book_source)
+                ReadManga.bookSource?.bookSourceName ?: context.getString(R.string.book_source)
             callBack.upSystemUiVisibility(true)
             callBack.upSystemUiVisibility(true)
             binding.tvSourceAction.isGone = false
             binding.tvSourceAction.isGone = false
         }
         }
@@ -211,7 +209,7 @@ class MangaMenu @JvmOverloads constructor(
                     val url = tvChapterUrl.text.toString()
                     val url = tvChapterUrl.text.toString()
                     putExtra("title", tvChapterName.text)
                     putExtra("title", tvChapterName.text)
                     putExtra("url", url)
                     putExtra("url", url)
-                    IntentData.put(url, ReadMange.bookSource?.getHeaderMap(true))
+                    IntentData.put(url, ReadManga.bookSource?.getHeaderMap(true))
                 }
                 }
             }
             }
         }
         }