From 864de368ee101aa3983cc753594fad46122dbb5c Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 22 Apr 2023 22:36:12 -0400 Subject: [PATCH] Make loader implementation classes internal (cherry picked from commit 418e6a8b3ac23c235e392fe64314a2e4994e209b) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt # app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt --- .../presentation/reader/ChapterTransition.kt | 3 +- .../tachiyomi/ui/reader/ReaderViewModel.kt | 6 +- .../ui/reader/loader/DirectoryPageLoader.kt | 12 +- .../ui/reader/loader/DownloadPageLoader.kt | 16 ++- .../ui/reader/loader/EpubPageLoader.kt | 24 ++-- .../ui/reader/loader/HttpPageLoader.kt | 118 +++++++++--------- .../tachiyomi/ui/reader/loader/PageLoader.kt | 20 +-- .../ui/reader/loader/RarPageLoader.kt | 35 ++---- .../ui/reader/loader/ZipPageLoader.kt | 12 +- 9 files changed, 109 insertions(+), 137 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/reader/ChapterTransition.kt b/app/src/main/java/eu/kanade/presentation/reader/ChapterTransition.kt index acb6f1847..531c94617 100644 --- a/app/src/main/java/eu/kanade/presentation/reader/ChapterTransition.kt +++ b/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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt index 9115a18e1..6abf9db9d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt @@ -31,8 +31,6 @@ import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.ui.reader.chapter.ReaderChapterItem 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 @@ -449,7 +447,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( @@ -539,7 +537,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 { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DirectoryPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DirectoryPageLoader.kt index c55ebddb6..837986b28 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DirectoryPageLoader.kt +++ b/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 { 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) {} } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt index 7223f0b4f..7518158e8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt +++ b/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 { val dbChapter = chapter.chapter val chapterPath = downloadProvider.findChapterDir(dbChapter.name, dbChapter.scanlator, /* SY --> */ manga.ogTitle /* SY <-- */, source) @@ -48,6 +41,11 @@ class DownloadPageLoader( } } + override fun recycle() { + super.recycle() + zipPageLoader?.recycle() + } + private suspend fun getPagesFromArchive(chapterPath: UniFile): List { // SY --> val loader = ZipPageLoader(File(chapterPath.filePath!!), context).also { zipPageLoader = it } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt index 6d581f2ba..324af51bf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt +++ b/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 { 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() + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt index 7a167c95c..9f207cc32 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt @@ -32,7 +32,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(), @@ -75,30 +75,7 @@ class HttpPageLoader( // EXH <-- } - /** - * 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, @@ -164,26 +141,6 @@ class HttpPageLoader( } } - /** - * 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 { - val pageIndex = currentPage.index - val pages = currentPage.chapter.pages ?: return emptyList() - if (pageIndex == pages.lastIndex) return emptyList() - - return pages - .subList(pageIndex + 1, min(pageIndex + 1 + amount, pages.size)) - .mapNotNull { - if (it.status == Page.State.QUEUE) { - PriorityPage(it, 0).apply { queue.offer(this) } - } else { - null - } - } - } - /** * Retries a page. This method is only called from user interaction on the viewer. */ @@ -206,23 +163,47 @@ class HttpPageLoader( } } + 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 + } + } + } + } + } + /** - * Data class used to keep ordering of pages in order to maintain priority. + * 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 class PriorityPage( - val page: ReaderPage, - val priority: Int, - ) : Comparable { - companion object { - private val idGenerator = AtomicInteger() - } + private fun preloadNextPages(currentPage: ReaderPage, amount: Int): List { + val pageIndex = currentPage.index + val pages = currentPage.chapter.pages ?: return emptyList() + if (pageIndex == pages.lastIndex) return emptyList() - 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) - } + return pages + .subList(pageIndex + 1, min(pageIndex + 1 + amount, pages.size)) + .mapNotNull { + if (it.status == Page.State.QUEUE) { + PriorityPage(it, 0).apply { queue.offer(this) } + } else { + null + } + } } /** @@ -265,3 +246,22 @@ class HttpPageLoader( } // EXH <-- } + +/** + * Data class used to keep ordering of pages in order to maintain priority. + */ +private class PriorityPage( + val page: ReaderPage, + val priority: Int, +) : Comparable { + 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) + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt index 720e81a43..164de6bda 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/PageLoader.kt +++ b/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 + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt index 6cd804dda..5374216ee 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/RarPageLoader.kt +++ b/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 { - 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) { } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt index 196bf142b..8e322c014 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ZipPageLoader.kt @@ -15,7 +15,7 @@ import java.nio.charset.StandardCharsets /** * Loader used to load a chapter from a .zip or .cbz file. */ -class ZipPageLoader( +internal class ZipPageLoader( file: File, // SY --> context: Context, @@ -58,7 +58,7 @@ class ZipPageLoader( /** * Returns the pages found on this zip archive ordered with a natural comparator. - */ + override suspend fun getPages(): List { // SY --> // Part can be removed after testing that there are no bugs with zip4j on some users devices @@ -95,10 +95,12 @@ class ZipPageLoader( // SY <-- } - /** - * No additional action required to load the page - */ override suspend fun loadPage(page: ReaderPage) { check(!isRecycled) } + + override fun recycle() { + super.recycle() + zip.close() + } }