Change Page.State to sealed interface (#1988)

(cherry picked from commit f1e2efcb37e2c623b769e979fa1c7e9e5ad7117d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ArchivePageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/EpubPageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
This commit is contained in:
AwkwardPeak7 2025-04-13 15:32:20 +05:00 committed by Jobobby04
parent b8267f1fef
commit 59887eed80
14 changed files with 58 additions and 58 deletions

View File

@ -179,7 +179,7 @@ class DownloadManager(
return files.sortedBy { it.name } return files.sortedBy { it.name }
.mapIndexed { i, file -> .mapIndexed { i, file ->
Page(i, uri = file.uri).apply { status = Page.State.READY } Page(i, uri = file.uri).apply { status = Page.State.Ready }
} }
} }

View File

@ -379,11 +379,11 @@ class Downloader(
flow { flow {
// Fetch image URL if necessary // Fetch image URL if necessary
if (page.imageUrl.isNullOrEmpty()) { if (page.imageUrl.isNullOrEmpty()) {
page.status = Page.State.LOAD_PAGE page.status = Page.State.LoadPage
try { try {
page.imageUrl = download.source.getImageUrl(page) page.imageUrl = download.source.getImageUrl(page)
} catch (e: Throwable) { } catch (e: Throwable) {
page.status = Page.State.ERROR page.status = Page.State.Error
} }
} }
@ -469,12 +469,12 @@ class Downloader(
page.uri = file.uri page.uri = file.uri
page.progress = 100 page.progress = 100
page.status = Page.State.READY page.status = Page.State.Ready
} catch (e: Throwable) { } catch (e: Throwable) {
if (e is CancellationException) throw e if (e is CancellationException) throw e
// Mark this page as error and allow to download the remaining // Mark this page as error and allow to download the remaining
page.progress = 0 page.progress = 0
page.status = Page.State.ERROR page.status = Page.State.Error
notifier.onError(e.message, download.chapter.name, download.manga.title, download.manga.id) notifier.onError(e.message, download.chapter.name, download.manga.title, download.manga.id)
} }
} }
@ -494,7 +494,7 @@ class Downloader(
filename: String, filename: String,
dataSaver: DataSaver, dataSaver: DataSaver,
): UniFile { ): UniFile {
page.status = Page.State.DOWNLOAD_IMAGE page.status = Page.State.DownloadImage
page.progress = 0 page.progress = 0
return flow { return flow {
val response = source.getImage(page, dataSaver) val response = source.getImage(page, dataSaver)

View File

@ -29,7 +29,7 @@ data class Download(
get() = pages?.sumOf(Page::progress) ?: 0 get() = pages?.sumOf(Page::progress) ?: 0
val downloadedImages: Int val downloadedImages: Int
get() = pages?.count { it.status == Page.State.READY } ?: 0 get() = pages?.count { it.status == Page.State.Ready } ?: 0
@Transient @Transient
private val _statusFlow = MutableStateFlow(State.NOT_DOWNLOADED) private val _statusFlow = MutableStateFlow(State.NOT_DOWNLOADED)

View File

@ -717,7 +717,7 @@ class ReaderActivity : BaseActivity() {
?.pages ?.pages
?.forEachIndexed { _, page -> ?.forEachIndexed { _, page ->
var shouldQueuePage = false var shouldQueuePage = false
if (page.status == Page.State.ERROR) { if (page.status == Page.State.Error) {
shouldQueuePage = true shouldQueuePage = true
} /*else if (page.status == Page.LOAD_PAGE || } /*else if (page.status == Page.LOAD_PAGE ||
page.status == Page.DOWNLOAD_IMAGE) { page.status == Page.DOWNLOAD_IMAGE) {
@ -725,7 +725,7 @@ class ReaderActivity : BaseActivity() {
}*/ }*/
if (shouldQueuePage) { if (shouldQueuePage) {
page.status = Page.State.QUEUE page.status = Page.State.Queue
} else { } else {
return@forEachIndexed return@forEachIndexed
} }
@ -758,11 +758,11 @@ class ReaderActivity : BaseActivity() {
return return
} }
if (curPage.status == Page.State.ERROR) { if (curPage.status == Page.State.Error) {
toast(SYMR.strings.eh_boost_page_errored) toast(SYMR.strings.eh_boost_page_errored)
} else if (curPage.status == Page.State.LOAD_PAGE || curPage.status == Page.State.DOWNLOAD_IMAGE) { } else if (curPage.status == Page.State.LoadPage || curPage.status == Page.State.DownloadImage) {
toast(SYMR.strings.eh_boost_page_downloading) toast(SYMR.strings.eh_boost_page_downloading)
} else if (curPage.status == Page.State.READY) { } else if (curPage.status == Page.State.Ready) {
toast(SYMR.strings.eh_boost_page_downloaded) toast(SYMR.strings.eh_boost_page_downloaded)
} else { } else {
val loader = (viewModel.state.value.viewerChapters?.currChapter?.pageLoader as? HttpPageLoader) val loader = (viewModel.state.value.viewerChapters?.currChapter?.pageLoader as? HttpPageLoader)

View File

@ -697,7 +697,7 @@ class ReaderViewModel @JvmOverloads constructor(
readerChapter.requestedPage = pageIndex readerChapter.requestedPage = pageIndex
chapterPageIndex = pageIndex chapterPageIndex = pageIndex
if (!incognitoMode && page.status != Page.State.ERROR) { if (!incognitoMode && page.status != Page.State.Error) {
readerChapter.chapter.last_page_read = pageIndex readerChapter.chapter.last_page_read = pageIndex
// SY --> // SY -->
@ -1071,7 +1071,7 @@ class ReaderViewModel @JvmOverloads constructor(
(state.value.dialog as? Dialog.PageActions)?.page (state.value.dialog as? Dialog.PageActions)?.page
} }
// SY <-- // SY <--
if (page?.status != Page.State.READY) return if (page?.status != Page.State.Ready) return
val manga = manga ?: return val manga = manga ?: return
val context = Injekt.get<Application>() val context = Injekt.get<Application>()
@ -1115,8 +1115,8 @@ class ReaderViewModel @JvmOverloads constructor(
val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages) val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages)
val bg = viewer.config.pageCanvasColor val bg = viewer.config.pageCanvasColor
if (firstPage.status != Page.State.READY) return if (firstPage.status != Page.State.Ready) return
if (secondPage?.status != Page.State.READY) return if (secondPage?.status != Page.State.Ready) return
val manga = manga ?: return val manga = manga ?: return
@ -1191,7 +1191,7 @@ class ReaderViewModel @JvmOverloads constructor(
(state.value.dialog as? Dialog.PageActions)?.page (state.value.dialog as? Dialog.PageActions)?.page
} }
// SY <-- // SY <--
if (page?.status != Page.State.READY) return if (page?.status != Page.State.Ready) return
val manga = manga ?: return val manga = manga ?: return
val context = Injekt.get<Application>() val context = Injekt.get<Application>()
@ -1223,8 +1223,8 @@ class ReaderViewModel @JvmOverloads constructor(
val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages) val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages)
val bg = viewer.config.pageCanvasColor val bg = viewer.config.pageCanvasColor
if (firstPage.status != Page.State.READY) return if (firstPage.status != Page.State.Ready) return
if (secondPage?.status != Page.State.READY) return if (secondPage?.status != Page.State.Ready) return
val manga = manga ?: return val manga = manga ?: return
val context = Injekt.get<Application>() val context = Injekt.get<Application>()
@ -1260,7 +1260,7 @@ class ReaderViewModel @JvmOverloads constructor(
(state.value.dialog as? Dialog.PageActions)?.page (state.value.dialog as? Dialog.PageActions)?.page
} }
// SY <-- // SY <--
if (page?.status != Page.State.READY) return if (page?.status != Page.State.Ready) return
val manga = manga ?: return val manga = manga ?: return
val stream = page.stream ?: return val stream = page.stream ?: return

View File

@ -90,7 +90,7 @@ internal class ArchivePageLoader(private val reader: ArchiveReader) : PageLoader
// SY --> // SY -->
stream = { imageBytes?.copyOf()?.inputStream() ?: reader.getInputStream(entry.name)!! } stream = { imageBytes?.copyOf()?.inputStream() ?: reader.getInputStream(entry.name)!! }
// SY <-- // SY <--
status = Page.State.READY status = Page.State.Ready
} }
} }
.toList() .toList()

View File

@ -21,7 +21,7 @@ internal class DirectoryPageLoader(val file: UniFile) : PageLoader() {
val streamFn = { file.openInputStream() } val streamFn = { file.openInputStream() }
ReaderPage(i).apply { ReaderPage(i).apply {
stream = streamFn stream = streamFn
status = Page.State.READY status = Page.State.Ready
} }
} }
.orEmpty() .orEmpty()

View File

@ -57,7 +57,7 @@ internal class DownloadPageLoader(
ReaderPage(page.index, page.url, page.imageUrl) { ReaderPage(page.index, page.url, page.imageUrl) {
context.contentResolver.openInputStream(page.uri ?: Uri.EMPTY)!! context.contentResolver.openInputStream(page.uri ?: Uri.EMPTY)!!
}.apply { }.apply {
status = Page.State.READY status = Page.State.Ready
} }
} }
} }

View File

@ -20,7 +20,7 @@ internal class EpubPageLoader(reader: ArchiveReader) : PageLoader() {
val streamFn = { epub.getInputStream(path)!! } val streamFn = { epub.getInputStream(path)!! }
ReaderPage(i).apply { ReaderPage(i).apply {
stream = streamFn stream = streamFn
status = Page.State.READY status = Page.State.Ready
} }
} }
} }

View File

@ -68,7 +68,7 @@ internal class HttpPageLoader(
emit(runInterruptible { queue.take() }.page) emit(runInterruptible { queue.take() }.page)
} }
} }
.filter { it.status == Page.State.QUEUE } .filter { it.status == Page.State.Queue }
.collect(::internalLoadPage) .collect(::internalLoadPage)
} }
// EXH --> // EXH -->
@ -98,7 +98,7 @@ internal class HttpPageLoader(
} }
if (readerPreferences.aggressivePageLoading().get()) { if (readerPreferences.aggressivePageLoading().get()) {
rp.forEach { rp.forEach {
if (it.status == Page.State.QUEUE) { if (it.status == Page.State.Queue) {
queue.offer(PriorityPage(it, 0)) queue.offer(PriorityPage(it, 0))
} }
} }
@ -114,17 +114,17 @@ internal class HttpPageLoader(
val imageUrl = page.imageUrl val imageUrl = page.imageUrl
// Check if the image has been deleted // Check if the image has been deleted
if (page.status == Page.State.READY && imageUrl != null && !chapterCache.isImageInCache(imageUrl)) { if (page.status == Page.State.Ready && imageUrl != null && !chapterCache.isImageInCache(imageUrl)) {
page.status = Page.State.QUEUE page.status = Page.State.Queue
} }
// Automatically retry failed pages when subscribed to this page // Automatically retry failed pages when subscribed to this page
if (page.status == Page.State.ERROR) { if (page.status == Page.State.Error) {
page.status = Page.State.QUEUE page.status = Page.State.Queue
} }
val queuedPages = mutableListOf<PriorityPage>() val queuedPages = mutableListOf<PriorityPage>()
if (page.status == Page.State.QUEUE) { if (page.status == Page.State.Queue) {
queuedPages += PriorityPage(page, 1).also { queue.offer(it) } queuedPages += PriorityPage(page, 1).also { queue.offer(it) }
} }
queuedPages += preloadNextPages(page, preloadSize) queuedPages += preloadNextPages(page, preloadSize)
@ -132,7 +132,7 @@ internal class HttpPageLoader(
suspendCancellableCoroutine<Nothing> { continuation -> suspendCancellableCoroutine<Nothing> { continuation ->
continuation.invokeOnCancellation { continuation.invokeOnCancellation {
queuedPages.forEach { queuedPages.forEach {
if (it.page.status == Page.State.QUEUE) { if (it.page.status == Page.State.Queue) {
queue.remove(it) queue.remove(it)
} }
} }
@ -144,8 +144,8 @@ internal class HttpPageLoader(
* Retries a page. This method is only called from user interaction on the viewer. * Retries a page. This method is only called from user interaction on the viewer.
*/ */
override fun retryPage(page: ReaderPage) { override fun retryPage(page: ReaderPage) {
if (page.status == Page.State.ERROR) { if (page.status == Page.State.Error) {
page.status = Page.State.QUEUE page.status = Page.State.Queue
} }
// EXH --> // EXH -->
// Grab a new image URL on EXH sources // Grab a new image URL on EXH sources
@ -196,7 +196,7 @@ internal class HttpPageLoader(
return pages return pages
.subList(pageIndex + 1, min(pageIndex + 1 + amount, pages.size)) .subList(pageIndex + 1, min(pageIndex + 1 + amount, pages.size))
.mapNotNull { .mapNotNull {
if (it.status == Page.State.QUEUE) { if (it.status == Page.State.Queue) {
PriorityPage(it, 0).apply { queue.offer(this) } PriorityPage(it, 0).apply { queue.offer(this) }
} else { } else {
null null
@ -213,21 +213,21 @@ internal class HttpPageLoader(
private suspend fun internalLoadPage(page: ReaderPage) { private suspend fun internalLoadPage(page: ReaderPage) {
try { try {
if (page.imageUrl.isNullOrEmpty()) { if (page.imageUrl.isNullOrEmpty()) {
page.status = Page.State.LOAD_PAGE page.status = Page.State.LoadPage
page.imageUrl = source.getImageUrl(page) page.imageUrl = source.getImageUrl(page)
} }
val imageUrl = page.imageUrl!! val imageUrl = page.imageUrl!!
if (!chapterCache.isImageInCache(imageUrl)) { if (!chapterCache.isImageInCache(imageUrl)) {
page.status = Page.State.DOWNLOAD_IMAGE page.status = Page.State.DownloadImage
val imageResponse = source.getImage(page, dataSaver) val imageResponse = source.getImage(page, dataSaver)
chapterCache.putImageToCache(imageUrl, imageResponse) chapterCache.putImageToCache(imageUrl, imageResponse)
} }
page.stream = { chapterCache.getImageFile(imageUrl).inputStream() } page.stream = { chapterCache.getImageFile(imageUrl).inputStream() }
page.status = Page.State.READY page.status = Page.State.Ready
} catch (e: Throwable) { } catch (e: Throwable) {
page.status = Page.State.ERROR page.status = Page.State.Error
if (e is CancellationException) { if (e is CancellationException) {
throw e throw e
} }
@ -236,7 +236,7 @@ internal class HttpPageLoader(
// EXH --> // EXH -->
fun boostPage(page: ReaderPage) { fun boostPage(page: ReaderPage) {
if (page.status == Page.State.QUEUE) { if (page.status == Page.State.Queue) {
scope.launchIO { scope.launchIO {
loadPage(page) loadPage(page)
} }

View File

@ -5,7 +5,7 @@ class InsertPage(val parent: ReaderPage) : ReaderPage(parent.index, parent.url,
override var chapter: ReaderChapter = parent.chapter override var chapter: ReaderChapter = parent.chapter
init { init {
status = State.READY status = State.Ready
stream = parent.stream stream = parent.stream
} }
} }

View File

@ -112,16 +112,16 @@ class PagerPageHolder(
} }
page.statusFlow.collectLatest { state -> page.statusFlow.collectLatest { state ->
when (state) { when (state) {
Page.State.QUEUE -> setQueued() Page.State.Queue -> setQueued()
Page.State.LOAD_PAGE -> setLoading() Page.State.LoadPage -> setLoading()
Page.State.DOWNLOAD_IMAGE -> { Page.State.DownloadImage -> {
setDownloading() setDownloading()
page.progressFlow.collectLatest { value -> page.progressFlow.collectLatest { value ->
progressIndicator?.setProgress(value) progressIndicator?.setProgress(value)
} }
} }
Page.State.READY -> setImage() Page.State.Ready -> setImage()
Page.State.ERROR -> setError() Page.State.Error -> setError()
} }
} }
} }

View File

@ -136,16 +136,16 @@ class WebtoonPageHolder(
} }
page.statusFlow.collectLatest { state -> page.statusFlow.collectLatest { state ->
when (state) { when (state) {
Page.State.QUEUE -> setQueued() Page.State.Queue -> setQueued()
Page.State.LOAD_PAGE -> setLoading() Page.State.LoadPage -> setLoading()
Page.State.DOWNLOAD_IMAGE -> { Page.State.DownloadImage -> {
setDownloading() setDownloading()
page.progressFlow.collectLatest { value -> page.progressFlow.collectLatest { value ->
progressIndicator.setProgress(value) progressIndicator.setProgress(value)
} }
} }
Page.State.READY -> setImage() Page.State.Ready -> setImage()
Page.State.ERROR -> setError() Page.State.Error -> setError()
} }
} }
} }

View File

@ -20,7 +20,7 @@ open class Page(
get() = index + 1 get() = index + 1
@Transient @Transient
private val _statusFlow = MutableStateFlow(State.QUEUE) private val _statusFlow = MutableStateFlow<State>(State.Queue)
@Transient @Transient
val statusFlow = _statusFlow.asStateFlow() val statusFlow = _statusFlow.asStateFlow()
@ -49,11 +49,11 @@ open class Page(
} }
} }
enum class State { sealed interface State {
QUEUE, data object Queue : State
LOAD_PAGE, data object LoadPage : State
DOWNLOAD_IMAGE, data object DownloadImage : State
READY, data object Ready : State
ERROR, data object Error : State
} }
} }