Эх сурвалжийг харах

Make loader implementation classes internal

arkon 1 жил өмнө
parent
commit
418e6a8b3a

+ 1 - 2
app/src/main/java/eu/kanade/presentation/reader/ChapterTransition.kt

@@ -28,7 +28,6 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Chapter
 import eu.kanade.tachiyomi.data.database.models.toDomainChapter
 import eu.kanade.tachiyomi.data.download.DownloadManager
-import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader
 import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition
 import tachiyomi.domain.chapter.service.calculateChapterGap
 import tachiyomi.domain.manga.model.Manga
@@ -43,7 +42,7 @@ fun ChapterTransition(
     manga ?: return
 
     val currChapter = transition.from.chapter
-    val currChapterDownloaded = transition.from.pageLoader is DownloadPageLoader
+    val currChapterDownloaded = transition.from.pageLoader?.isLocal == true
 
     val goingToChapter = transition.to?.chapter
     val goingToChapterDownloaded = if (goingToChapter != null) {

+ 2 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt

@@ -25,8 +25,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
 import eu.kanade.tachiyomi.source.model.Page
 import eu.kanade.tachiyomi.source.online.HttpSource
 import eu.kanade.tachiyomi.ui.reader.loader.ChapterLoader
-import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader
-import eu.kanade.tachiyomi.ui.reader.loader.HttpPageLoader
 import eu.kanade.tachiyomi.ui.reader.model.InsertPage
 import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
 import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
@@ -365,7 +363,7 @@ class ReaderViewModel(
             return
         }
 
-        if (chapter.pageLoader is HttpPageLoader) {
+        if (chapter.pageLoader?.isLocal == false) {
             val manga = manga ?: return
             val dbChapter = chapter.chapter
             val isDownloaded = downloadManager.isChapterDownloaded(
@@ -440,7 +438,7 @@ class ReaderViewModel(
         if (amount == 0 || !manga.favorite) return
 
         // Only download ahead if current + next chapter is already downloaded too to avoid jank
-        if (getCurrentChapter()?.pageLoader !is DownloadPageLoader) return
+        if (getCurrentChapter()?.pageLoader?.isLocal == true) return
         val nextChapter = state.value.viewerChapters?.nextChapter?.chapter ?: return
 
         viewModelScope.launchIO {

+ 3 - 9
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DirectoryPageLoader.kt

@@ -10,11 +10,10 @@ import java.io.FileInputStream
 /**
  * Loader used to load a chapter from a directory given on [file].
  */
-class DirectoryPageLoader(val file: File) : PageLoader() {
+internal class DirectoryPageLoader(val file: File) : PageLoader() {
+
+    override var isLocal: Boolean = true
 
-    /**
-     * Returns the pages found on this directory ordered with a natural comparator.
-     */
     override suspend fun getPages(): List<ReaderPage> {
         return file.listFiles()
             ?.filter { !it.isDirectory && ImageUtil.isImage(it.name) { FileInputStream(it) } }
@@ -28,9 +27,4 @@ class DirectoryPageLoader(val file: File) : PageLoader() {
             }
             .orEmpty()
     }
-
-    /**
-     * No additional action required to load the page
-     */
-    override suspend fun loadPage(page: ReaderPage) {}
 }

+ 7 - 9
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt

@@ -17,7 +17,7 @@ import java.io.File
 /**
  * Loader used to load a chapter from the downloaded chapters.
  */
-class DownloadPageLoader(
+internal class DownloadPageLoader(
     private val chapter: ReaderChapter,
     private val manga: Manga,
     private val source: Source,
@@ -25,19 +25,12 @@ class DownloadPageLoader(
     private val downloadProvider: DownloadProvider,
 ) : PageLoader() {
 
-    // Needed to open input streams
     private val context: Application by injectLazy()
 
     private var zipPageLoader: ZipPageLoader? = null
 
-    override fun recycle() {
-        super.recycle()
-        zipPageLoader?.recycle()
-    }
+    override var isLocal: Boolean = true
 
-    /**
-     * Returns the pages found on this downloaded chapter.
-     */
     override suspend fun getPages(): List<ReaderPage> {
         val dbChapter = chapter.chapter
         val chapterPath = downloadProvider.findChapterDir(dbChapter.name, dbChapter.scanlator, manga.title, source)
@@ -48,6 +41,11 @@ class DownloadPageLoader(
         }
     }
 
+    override fun recycle() {
+        super.recycle()
+        zipPageLoader?.recycle()
+    }
+
     private suspend fun getPagesFromArchive(chapterPath: UniFile): List<ReaderPage> {
         val loader = ZipPageLoader(File(chapterPath.filePath!!)).also { zipPageLoader = it }
         return loader.getPages()

+ 7 - 17
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt

@@ -8,24 +8,12 @@ import java.io.File
 /**
  * Loader used to load a chapter from a .epub file.
  */
-class EpubPageLoader(file: File) : PageLoader() {
+internal class EpubPageLoader(file: File) : PageLoader() {
 
-    /**
-     * The epub file.
-     */
     private val epub = EpubFile(file)
 
-    /**
-     * Recycles this loader and the open zip.
-     */
-    override fun recycle() {
-        super.recycle()
-        epub.close()
-    }
+    override var isLocal: Boolean = true
 
-    /**
-     * Returns the pages found on this zip archive ordered with a natural comparator.
-     */
     override suspend fun getPages(): List<ReaderPage> {
         return epub.getImagesFromPages()
             .mapIndexed { i, path ->
@@ -37,10 +25,12 @@ class EpubPageLoader(file: File) : PageLoader() {
             }
     }
 
-    /**
-     * No additional action required to load the page
-     */
     override suspend fun loadPage(page: ReaderPage) {
         check(!isRecycled)
     }
+
+    override fun recycle() {
+        super.recycle()
+        epub.close()
+    }
 }

+ 54 - 54
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt

@@ -27,7 +27,7 @@ import kotlin.math.min
 /**
  * Loader used to load chapters from an online source.
  */
-class HttpPageLoader(
+internal class HttpPageLoader(
     private val chapter: ReaderChapter,
     private val source: HttpSource,
     private val chapterCache: ChapterCache = Injekt.get(),
@@ -56,30 +56,7 @@ class HttpPageLoader(
         }
     }
 
-    /**
-     * Recycles this loader and the active subscriptions and queue.
-     */
-    override fun recycle() {
-        super.recycle()
-        scope.cancel()
-        queue.clear()
-
-        // Cache current page list progress for online chapters to allow a faster reopen
-        val pages = chapter.pages
-        if (pages != null) {
-            launchIO {
-                try {
-                    // Convert to pages without reader information
-                    val pagesToSave = pages.map { Page(it.index, it.url, it.imageUrl) }
-                    chapterCache.putPageListToCache(chapter.chapter.toDomainChapter()!!, pagesToSave)
-                } catch (e: Throwable) {
-                    if (e is CancellationException) {
-                        throw e
-                    }
-                }
-            }
-        }
-    }
+    override var isLocal: Boolean = false
 
     /**
      * Returns the page list for a chapter. It tries to return the page list from the local cache,
@@ -135,8 +112,41 @@ class HttpPageLoader(
         }
     }
 
+    /**
+     * Retries a page. This method is only called from user interaction on the viewer.
+     */
+    override fun retryPage(page: ReaderPage) {
+        if (page.status == Page.State.ERROR) {
+            page.status = Page.State.QUEUE
+        }
+        queue.offer(PriorityPage(page, 2))
+    }
+
+    override fun recycle() {
+        super.recycle()
+        scope.cancel()
+        queue.clear()
+
+        // Cache current page list progress for online chapters to allow a faster reopen
+        val pages = chapter.pages
+        if (pages != null) {
+            launchIO {
+                try {
+                    // Convert to pages without reader information
+                    val pagesToSave = pages.map { Page(it.index, it.url, it.imageUrl) }
+                    chapterCache.putPageListToCache(chapter.chapter.toDomainChapter()!!, pagesToSave)
+                } catch (e: Throwable) {
+                    if (e is CancellationException) {
+                        throw e
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Preloads the given [amount] of pages after the [currentPage] with a lower priority.
+     *
      * @return a list of [PriorityPage] that were added to the [queue]
      */
     private fun preloadNextPages(currentPage: ReaderPage, amount: Int): List<PriorityPage> {
@@ -155,35 +165,6 @@ class HttpPageLoader(
             }
     }
 
-    /**
-     * Retries a page. This method is only called from user interaction on the viewer.
-     */
-    override fun retryPage(page: ReaderPage) {
-        if (page.status == Page.State.ERROR) {
-            page.status = Page.State.QUEUE
-        }
-        queue.offer(PriorityPage(page, 2))
-    }
-
-    /**
-     * Data class used to keep ordering of pages in order to maintain priority.
-     */
-    private class PriorityPage(
-        val page: ReaderPage,
-        val priority: Int,
-    ) : Comparable<PriorityPage> {
-        companion object {
-            private val idGenerator = AtomicInteger()
-        }
-
-        private val identifier = idGenerator.incrementAndGet()
-
-        override fun compareTo(other: PriorityPage): Int {
-            val p = other.priority.compareTo(priority)
-            return if (p != 0) p else identifier.compareTo(other.identifier)
-        }
-    }
-
     /**
      * Loads the page, retrieving the image URL and downloading the image if necessary.
      * Downloaded images are stored in the chapter cache.
@@ -214,3 +195,22 @@ class HttpPageLoader(
         }
     }
 }
+
+/**
+ * Data class used to keep ordering of pages in order to maintain priority.
+ */
+private class PriorityPage(
+    val page: ReaderPage,
+    val priority: Int,
+) : Comparable<PriorityPage> {
+    companion object {
+        private val idGenerator = AtomicInteger()
+    }
+
+    private val identifier = idGenerator.incrementAndGet()
+
+    override fun compareTo(other: PriorityPage): Int {
+        val p = other.priority.compareTo(priority)
+        return if (p != 0) p else identifier.compareTo(other.identifier)
+    }
+}

+ 11 - 9
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt

@@ -15,14 +15,7 @@ abstract class PageLoader {
     var isRecycled = false
         private set
 
-    /**
-     * Recycles this loader. Implementations must override this method to clean up any active
-     * resources.
-     */
-    @CallSuper
-    open fun recycle() {
-        isRecycled = true
-    }
+    abstract var isLocal: Boolean
 
     /**
      * Returns the list of pages of a chapter.
@@ -34,11 +27,20 @@ abstract class PageLoader {
      * Progress of the page loading should be followed via [page.statusFlow].
      * [loadPage] is not currently guaranteed to complete, so it should be launched asynchronously.
      */
-    abstract suspend fun loadPage(page: ReaderPage)
+    open suspend fun loadPage(page: ReaderPage) {}
 
     /**
      * Retries the given [page] in case it failed to load. This method only makes sense when an
      * online source is used.
      */
     open fun retryPage(page: ReaderPage) {}
+
+    /**
+     * Recycles this loader. Implementations must override this method to clean up any active
+     * resources.
+     */
+    @CallSuper
+    open fun recycle() {
+        isRecycled = true
+    }
 }

+ 12 - 23
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt

@@ -15,34 +15,20 @@ import java.util.concurrent.Executors
 /**
  * Loader used to load a chapter from a .rar or .cbr file.
  */
-class RarPageLoader(file: File) : PageLoader() {
+internal class RarPageLoader(file: File) : PageLoader() {
 
-    /**
-     * The rar archive to load pages from.
-     */
-    private val archive = Archive(file)
+    private val rar = Archive(file)
 
     /**
      * Pool for copying compressed files to an input stream.
      */
     private val pool = Executors.newFixedThreadPool(1)
 
-    /**
-     * Recycles this loader and the open archive.
-     */
-    override fun recycle() {
-        super.recycle()
-        archive.close()
-        pool.shutdown()
-    }
+    override var isLocal: Boolean = true
 
-    /**
-     * Returns an RxJava Single containing the pages found on this rar archive ordered with a natural
-     * comparator.
-     */
     override suspend fun getPages(): List<ReaderPage> {
-        return archive.fileHeaders.asSequence()
-            .filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { archive.getInputStream(it) } }
+        return rar.fileHeaders.asSequence()
+            .filter { !it.isDirectory && ImageUtil.isImage(it.fileName) { rar.getInputStream(it) } }
             .sortedWith { f1, f2 -> f1.fileName.compareToCaseInsensitiveNaturalOrder(f2.fileName) }
             .mapIndexed { i, header ->
                 ReaderPage(i).apply {
@@ -53,13 +39,16 @@ class RarPageLoader(file: File) : PageLoader() {
             .toList()
     }
 
-    /**
-     * No additional action required to load the page
-     */
     override suspend fun loadPage(page: ReaderPage) {
         check(!isRecycled)
     }
 
+    override fun recycle() {
+        super.recycle()
+        rar.close()
+        pool.shutdown()
+    }
+
     /**
      * Returns an input stream for the given [header].
      */
@@ -69,7 +58,7 @@ class RarPageLoader(file: File) : PageLoader() {
         pool.execute {
             try {
                 pipeOut.use {
-                    archive.extractFile(header, it)
+                    rar.extractFile(header, it)
                 }
             } catch (e: Exception) {
             }

+ 7 - 17
app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt

@@ -12,28 +12,16 @@ import java.util.zip.ZipFile
 /**
  * Loader used to load a chapter from a .zip or .cbz file.
  */
-class ZipPageLoader(file: File) : PageLoader() {
+internal class ZipPageLoader(file: File) : PageLoader() {
 
-    /**
-     * The zip file to load pages from.
-     */
     private val zip = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
         ZipFile(file, StandardCharsets.ISO_8859_1)
     } else {
         ZipFile(file)
     }
 
-    /**
-     * Recycles this loader and the open zip.
-     */
-    override fun recycle() {
-        super.recycle()
-        zip.close()
-    }
+    override var isLocal: Boolean = true
 
-    /**
-     * Returns the pages found on this zip archive ordered with a natural comparator.
-     */
     override suspend fun getPages(): List<ReaderPage> {
         return zip.entries().asSequence()
             .filter { !it.isDirectory && ImageUtil.isImage(it.name) { zip.getInputStream(it) } }
@@ -47,10 +35,12 @@ class ZipPageLoader(file: File) : PageLoader() {
             .toList()
     }
 
-    /**
-     * No additional action required to load the page
-     */
     override suspend fun loadPage(page: ReaderPage) {
         check(!isRecycled)
     }
+
+    override fun recycle() {
+        super.recycle()
+        zip.close()
+    }
 }