Fix loading local manga

master
Koitharu 9 months ago
parent d641e7933d
commit 0b0373021e
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -8,6 +8,8 @@ plugins {
id 'dagger.hilt.android.plugin' id 'dagger.hilt.android.plugin'
id 'androidx.room' id 'androidx.room'
id 'org.jetbrains.kotlin.plugin.serialization' id 'org.jetbrains.kotlin.plugin.serialization'
// enable if needed
// id 'dev.reformator.stacktracedecoroutinator'
} }
android { android {

@ -173,6 +173,7 @@ class AppShortcutManager @Inject constructor(
coil.execute( coil.execute(
ImageRequest.Builder(context) ImageRequest.Builder(context)
.data(source.faviconUri()) .data(source.faviconUri())
.mangaSourceExtra(source)
.size(iconSize) .size(iconSize)
.scale(Scale.FIT) .scale(Scale.FIT)
.build(), .build(),

@ -6,6 +6,7 @@ import android.database.sqlite.SQLiteFullException
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import coil3.network.HttpException import coil3.network.HttpException
import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException import com.davemorrissey.labs.subscaleview.decoder.ImageDecodeException
import kotlinx.coroutines.CancellationException
import okhttp3.Response import okhttp3.Response
import okhttp3.internal.http2.StreamResetException import okhttp3.internal.http2.StreamResetException
import okio.FileNotFoundException import okio.FileNotFoundException
@ -64,6 +65,7 @@ fun Throwable.getDisplayMessage(resources: Resources): String = getDisplayMessag
?: resources.getString(R.string.error_occurred) ?: resources.getString(R.string.error_occurred)
private fun Throwable.getDisplayMessageOrNull(resources: Resources): String? = when (this) { private fun Throwable.getDisplayMessageOrNull(resources: Resources): String? = when (this) {
is CancellationException -> cause?.getDisplayMessageOrNull(resources) ?: message
is CaughtException -> cause.getDisplayMessageOrNull(resources) is CaughtException -> cause.getDisplayMessageOrNull(resources)
is WrapperIOException -> cause.getDisplayMessageOrNull(resources) is WrapperIOException -> cause.getDisplayMessageOrNull(resources)
is ScrobblerAuthRequiredException -> resources.getString( is ScrobblerAuthRequiredException -> resources.getString(

@ -9,11 +9,9 @@ import androidx.core.text.parseAsHtml
import coil3.request.CachePolicy import coil3.request.CachePolicy
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
@ -66,7 +64,6 @@ class DetailsLoadUseCase @Inject constructor(
loadRemote(manga, override, force) loadRemote(manga, override, force)
} }
}.distinctUntilChanged() }.distinctUntilChanged()
.buffer(Channel.UNLIMITED)
.flowOn(Dispatchers.Default) .flowOn(Dispatchers.Default)
/** /**

@ -1,7 +1,6 @@
package org.koitharu.kotatsu.reader.ui package org.koitharu.kotatsu.reader.ui
import android.net.Uri import android.net.Uri
import android.util.Log
import androidx.annotation.AnyThread import androidx.annotation.AnyThread
import androidx.annotation.MainThread import androidx.annotation.MainThread
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
@ -396,7 +395,8 @@ class ReaderViewModel @Inject constructor(
private fun loadImpl() { private fun loadImpl() {
loadingJob = launchLoadingJob(Dispatchers.Default + EventExceptionHandler(onLoadingError)) { loadingJob = launchLoadingJob(Dispatchers.Default + EventExceptionHandler(onLoadingError)) {
val exception = try { var exception: Exception? = null
try {
detailsLoadUseCase(intent, force = false) detailsLoadUseCase(intent, force = false)
.collect { details -> .collect { details ->
if (mangaDetails.value == null) { if (mangaDetails.value == null) {
@ -417,7 +417,13 @@ class ReaderViewModel @Inject constructor(
val branch = chaptersLoader.peekChapter(newState.chapterId)?.branch val branch = chaptersLoader.peekChapter(newState.chapterId)?.branch
selectedBranch.value = branch selectedBranch.value = branch
readerMode.value = mode readerMode.value = mode
chaptersLoader.loadSingleChapter(newState.chapterId) try {
chaptersLoader.loadSingleChapter(newState.chapterId)
} catch (e: Exception) {
readingState.value = null // try next time
exception = e.mergeWith(exception)
return@collect
}
} }
mangaDetails.value = details.filterChapters(selectedBranch.value) mangaDetails.value = details.filterChapters(selectedBranch.value)
@ -431,19 +437,18 @@ class ReaderViewModel @Inject constructor(
notifyStateChanged() notifyStateChanged()
content.value = ReaderContent(chaptersLoader.snapshot(), readingState.value) content.value = ReaderContent(chaptersLoader.snapshot(), readingState.value)
} }
null // no errors
} catch (e: CancellationException) { } catch (e: CancellationException) {
throw e throw e
} catch (e: Exception) { } catch (e: Exception) {
e exception = e.mergeWith(exception)
} }
if (readingState.value == null) { if (readingState.value == null) {
onLoadingError.call( onLoadingError.call(
exception ?: IllegalStateException("Unable to load manga. This should never happen. Please report"), exception ?: IllegalStateException("Unable to load manga. This should never happen. Please report"),
) )
} else if (exception != null) { } else exception?.let { e ->
// manga has been loaded but error occurred // manga has been loaded but error occurred
errorEvent.call(exception) errorEvent.call(e)
} }
} }
} }
@ -576,4 +581,11 @@ class ReaderViewModel @Inject constructor(
val preferredBranch = requestedBranch ?: manga.getPreferredBranch(null) val preferredBranch = requestedBranch ?: manga.getPreferredBranch(null)
return ReaderState(manga, preferredBranch) return ReaderState(manga, preferredBranch)
} }
private fun Exception.mergeWith(other: Exception?): Exception = if (other == null) {
this
} else {
other.addSuppressed(this)
other
}
} }

@ -5,4 +5,5 @@ plugins {
alias(libs.plugins.ksp) apply false alias(libs.plugins.ksp) apply false
alias(libs.plugins.room) apply false alias(libs.plugins.room) apply false
alias(libs.plugins.kotlinx.serizliation) apply false alias(libs.plugins.kotlinx.serizliation) apply false
// alias(libs.plugins.decoroutinator) apply false
} }

@ -13,7 +13,7 @@ constraintlayout = "2.2.1"
coreKtx = "1.16.0" coreKtx = "1.16.0"
coroutines = "1.10.2" coroutines = "1.10.2"
dagger = "2.56.2" dagger = "2.56.2"
decoroutinator = "2.5.4" decoroutinator = "2.5.5"
desugar = "2.1.5" desugar = "2.1.5"
diskLruCache = "1.5" diskLruCache = "1.5"
documentfile = "1.1.0" documentfile = "1.1.0"

Loading…
Cancel
Save