diff --git a/app/build.gradle b/app/build.gradle index 7c904e60a..b1a41250d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdkVersion 21 targetSdkVersion 32 - versionCode 416 - versionName '3.4.4' + versionCode 417 + versionName '3.4.5' generatedDensities = [] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -79,7 +79,7 @@ afterEvaluate { } } dependencies { - implementation('com.github.nv95:kotatsu-parsers:6af8cec134') { + implementation('com.github.nv95:kotatsu-parsers:30071709af') { exclude group: 'org.json', module: 'json' } @@ -99,7 +99,7 @@ dependencies { implementation 'androidx.preference:preference-ktx:1.2.0' implementation 'androidx.work:work-runtime-ktx:2.7.1' implementation 'androidx.biometric:biometric-ktx:1.2.0-alpha04' - implementation 'com.google.android.material:material:1.7.0-alpha02' + implementation 'com.google.android.material:material:1.7.0-alpha03' //noinspection LifecycleAnnotationProcessorWithJava8 kapt 'androidx.lifecycle:lifecycle-compiler:2.5.0' diff --git a/app/src/main/java/org/koitharu/kotatsu/core/exceptions/CaughtException.kt b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/CaughtException.kt new file mode 100644 index 000000000..907917537 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/CaughtException.kt @@ -0,0 +1,3 @@ +package org.koitharu.kotatsu.core.exceptions + +class CaughtException(cause: Throwable, override val message: String?) : RuntimeException(cause) \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsDelegate.kt index c6c45ecc1..39ad3003b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsDelegate.kt @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.details.ui import androidx.core.os.LocaleListCompat import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import org.acra.ACRA import org.koitharu.kotatsu.base.domain.MangaDataRepository import org.koitharu.kotatsu.base.domain.MangaIntent import org.koitharu.kotatsu.core.exceptions.MangaNotFoundException @@ -14,7 +13,6 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.details.ui.model.toListItem import org.koitharu.kotatsu.history.domain.HistoryRepository import org.koitharu.kotatsu.local.domain.LocalMangaRepository -import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaSource @@ -22,7 +20,6 @@ import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.toTitleCase import org.koitharu.kotatsu.utils.ext.iterator import org.koitharu.kotatsu.utils.ext.printStackTraceDebug -import org.koitharu.kotatsu.utils.ext.setCurrentManga class MangaDetailsDelegate( private val intent: MangaIntent, @@ -45,7 +42,6 @@ class MangaDetailsDelegate( suspend fun doLoad() { var manga = mangaDataRepository.resolveIntent(intent) ?: throw MangaNotFoundException("Cannot find manga") - ACRA.setCurrentManga(manga) mangaData.value = manga manga = MangaRepository(manga.source).getDetails(manga) // find default branch diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index a9f563d1f..e761ce1c6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -346,14 +346,14 @@ class ReaderActivity : menuItem.setIcon(if (isAdded) R.drawable.ic_bookmark_added else R.drawable.ic_bookmark) } - private fun onUiStateChanged(uiState: ReaderUiState, previous: ReaderUiState?) { - title = uiState.chapterName ?: uiState.mangaName ?: getString(R.string.loading_) - supportActionBar?.subtitle = if (uiState.chapterNumber in 1..uiState.chaptersTotal) { + private fun onUiStateChanged(uiState: ReaderUiState?, previous: ReaderUiState?) { + title = uiState?.chapterName ?: uiState?.mangaName ?: getString(R.string.loading_) + supportActionBar?.subtitle = if (uiState != null && uiState.chapterNumber in 1..uiState.chaptersTotal) { getString(R.string.chapter_d_of_d, uiState.chapterNumber, uiState.chaptersTotal) } else { null } - if (previous?.chapterName != null && uiState.chapterName != previous.chapterName) { + if (uiState != null && previous?.chapterName != null && uiState.chapterName != previous.chapterName) { if (!uiState.chapterName.isNullOrEmpty()) { binding.toastView.showTemporary(uiState.chapterName, TOAST_DURATION) } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt index ea93e7267..6d8b1f0f6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt @@ -8,7 +8,6 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import kotlinx.coroutines.* import kotlinx.coroutines.flow.* -import org.acra.ACRA import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.domain.MangaDataRepository import org.koitharu.kotatsu.base.domain.MangaIntent @@ -32,7 +31,6 @@ import org.koitharu.kotatsu.utils.SingleLiveEvent import org.koitharu.kotatsu.utils.ext.asLiveDataDistinct import org.koitharu.kotatsu.utils.ext.printStackTraceDebug import org.koitharu.kotatsu.utils.ext.processLifecycleScope -import org.koitharu.kotatsu.utils.ext.setCurrentManga import java.util.* private const val BOUNDS_PAGE_OFFSET = 2 @@ -73,7 +71,7 @@ class ReaderViewModel( chapterNumber = chapter?.number ?: 0, chaptersTotal = chapters.size() ) - }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) + }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, null) val content = MutableLiveData(ReaderContent(emptyList(), null)) val manga: Manga? @@ -91,7 +89,7 @@ class ReaderViewModel( ) { manga, policy -> policy == ScreenshotsPolicy.BLOCK_ALL || (policy == ScreenshotsPolicy.BLOCK_NSFW && manga != null && manga.isNsfw) - }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) + }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, false) val onZoomChanged = SingleLiveEvent() @@ -103,7 +101,7 @@ class ReaderViewModel( bookmarksRepository.observeBookmark(manga, state.chapterId, state.page) .map { it != null } } - }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default) + }.asLiveDataDistinct(viewModelScope.coroutineContext + Dispatchers.Default, false) init { loadImpl() @@ -262,7 +260,6 @@ class ReaderViewModel( private fun loadImpl() { loadingJob = launchLoadingJob(Dispatchers.Default) { var manga = dataRepository.resolveIntent(intent) ?: throw MangaNotFoundException("Cannot find manga") - ACRA.setCurrentManga(manga) mangaData.value = manga val repo = MangaRepository(manga.source) manga = repo.getDetails(manga) diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ThrowableExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ThrowableExt.kt index 7b7f76408..79ee12775 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ThrowableExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ThrowableExt.kt @@ -3,19 +3,15 @@ package org.koitharu.kotatsu.utils.ext import android.content.ActivityNotFoundException import android.content.res.Resources import okio.FileNotFoundException -import org.acra.ACRA import org.acra.ktx.sendWithAcra import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException -import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException -import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException -import org.koitharu.kotatsu.core.exceptions.WrongPasswordException +import org.koitharu.kotatsu.core.exceptions.* import org.koitharu.kotatsu.parsers.exception.AuthRequiredException +import org.koitharu.kotatsu.parsers.exception.ContentUnavailableException import org.koitharu.kotatsu.parsers.exception.ParseException -import org.koitharu.kotatsu.parsers.model.Manga import java.net.SocketTimeoutException -fun Throwable.getDisplayMessage(resources: Resources) = when (this) { +fun Throwable.getDisplayMessage(resources: Resources): String = when (this) { is AuthRequiredException -> resources.getString(R.string.auth_required) is CloudFlareProtectedException -> resources.getString(R.string.captcha_required) is ActivityNotFoundException, @@ -23,22 +19,21 @@ fun Throwable.getDisplayMessage(resources: Resources) = when (this) { is UnsupportedFileException -> resources.getString(R.string.text_file_not_supported) is FileNotFoundException -> resources.getString(R.string.file_not_found) is EmptyHistoryException -> resources.getString(R.string.history_is_empty) + is ContentUnavailableException -> message + is ParseException -> shortMessage is SocketTimeoutException -> resources.getString(R.string.network_error) is WrongPasswordException -> resources.getString(R.string.wrong_password) - else -> localizedMessage ?: resources.getString(R.string.error_occurred) -} + else -> localizedMessage +} ?: resources.getString(R.string.error_occurred) fun Throwable.isReportable(): Boolean { if (this !is Exception) { return true } - return this is ParseException || this is IllegalArgumentException || this is IllegalStateException + return this is ParseException || this is IllegalArgumentException || + this is IllegalStateException || this is RuntimeException } fun Throwable.report(message: String?) { CaughtException(this, message).sendWithAcra() -} - -fun ACRA.setCurrentManga(manga: Manga?) = errorReporter.putCustomData("manga", manga?.publicUrl.toString()) - -private class CaughtException(cause: Throwable, override val message: String?) : RuntimeException(cause) \ No newline at end of file +} \ No newline at end of file