From 6f2bb18d727c089a6a49a3701c35d589de669e18 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 19 Feb 2023 16:44:58 -0500 Subject: [PATCH 01/16] Avoid crash when loading invalid extension package (cherry picked from commit 3d7c136320da3b5842a51d7dbb9e82cf74144f3f) --- .../eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt index 7ecb4bd52..41eb2e0f6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionLoader.kt @@ -126,8 +126,8 @@ internal object ExtensionLoader { } // Validate lib version - val libVersion = versionName.substringBeforeLast('.').toDouble() - if (libVersion < LIB_VERSION_MIN || libVersion > LIB_VERSION_MAX) { + val libVersion = versionName.substringBeforeLast('.').toDoubleOrNull() + if (libVersion == null || libVersion < LIB_VERSION_MIN || libVersion > LIB_VERSION_MAX) { logcat(LogPriority.WARN) { "Lib version is $libVersion, while only versions " + "$LIB_VERSION_MIN to $LIB_VERSION_MAX are allowed" @@ -136,7 +136,6 @@ internal object ExtensionLoader { } val signatureHash = getSignatureHash(pkgInfo) - if (signatureHash == null) { logcat(LogPriority.WARN) { "Package $pkgName isn't signed" } return LoadResult.Error From 4498b10a1061bc36708ce065a799ac561c66ed16 Mon Sep 17 00:00:00 2001 From: arkon Date: Tue, 21 Feb 2023 12:25:46 -0500 Subject: [PATCH 02/16] Fix occasional crash when opening library settings sheet See https://stackoverflow.com/questions/47648689/sealed-classs-objects-mysteriously-becoming-null-when-referenced-by-other-compa (cherry picked from commit c0e2eb211daefe47803d93161f896c6d5011a0ff) --- .../java/tachiyomi/domain/library/model/LibraryDisplayMode.kt | 2 +- .../library/model/{LibrarySort.kt => LibrarySortMode.kt} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename domain/src/main/java/tachiyomi/domain/library/model/{LibrarySort.kt => LibrarySortMode.kt} (93%) diff --git a/domain/src/main/java/tachiyomi/domain/library/model/LibraryDisplayMode.kt b/domain/src/main/java/tachiyomi/domain/library/model/LibraryDisplayMode.kt index 236d00235..f317db671 100644 --- a/domain/src/main/java/tachiyomi/domain/library/model/LibraryDisplayMode.kt +++ b/domain/src/main/java/tachiyomi/domain/library/model/LibraryDisplayMode.kt @@ -24,7 +24,7 @@ sealed class LibraryDisplayMode( } companion object { - val values = setOf(CompactGrid, ComfortableGrid, List, CoverOnlyGrid) + val values by lazy { setOf(CompactGrid, ComfortableGrid, List, CoverOnlyGrid) } val default = CompactGrid fun valueOf(flag: Long?): LibraryDisplayMode { diff --git a/domain/src/main/java/tachiyomi/domain/library/model/LibrarySort.kt b/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt similarity index 93% rename from domain/src/main/java/tachiyomi/domain/library/model/LibrarySort.kt rename to domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt index 1d133724c..9507aaa5c 100644 --- a/domain/src/main/java/tachiyomi/domain/library/model/LibrarySort.kt +++ b/domain/src/main/java/tachiyomi/domain/library/model/LibrarySortMode.kt @@ -65,8 +65,8 @@ data class LibrarySort( } companion object { - val types = setOf(Type.Alphabetical, Type.LastRead, Type.LastUpdate, Type.UnreadCount, Type.TotalChapters, Type.LatestChapter, Type.ChapterFetchDate, Type.DateAdded) - val directions = setOf(Direction.Ascending, Direction.Descending) + val types by lazy { setOf(Type.Alphabetical, Type.LastRead, Type.LastUpdate, Type.UnreadCount, Type.TotalChapters, Type.LatestChapter, Type.ChapterFetchDate, Type.DateAdded) } + val directions by lazy { setOf(Direction.Ascending, Direction.Descending) } val default = LibrarySort(Type.Alphabetical, Direction.Ascending) fun valueOf(flag: Long): LibrarySort { From 08e6487a9aa169ec40be29514da817f67bde517e Mon Sep 17 00:00:00 2001 From: Two-Ai <81279822+Two-Ai@users.noreply.github.com> Date: Tue, 21 Feb 2023 18:21:00 -0500 Subject: [PATCH 03/16] Fix download queue page count display bug (#9126) When restarting a download, the page count would display as 0 until the first page download completion, after all the existing pages were rechecked. To fix, calculate downloadedImages from pages instead of relying on the downloader to reset and increment the count. (cherry picked from commit 779df32e98f2a020ca6a4f79c0748dd9f5b16873) --- .../java/eu/kanade/tachiyomi/data/download/Downloader.kt | 2 -- .../java/eu/kanade/tachiyomi/data/download/model/Download.kt | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 9f350b7dd..1e52470f1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -339,7 +339,6 @@ class Downloader( ?.filter { it.name!!.endsWith(".tmp") } ?.forEach { it.delete() } - download.downloadedImages = 0 download.status = Download.State.DOWNLOADING } // Get all the URLs to the source images, fetch pages if necessary @@ -403,7 +402,6 @@ class Downloader( } page.uri = file.uri page.progress = 100 - download.downloadedImages++ page.status = Page.State.READY } .map { page } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/model/Download.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/model/Download.kt index 38ddacddb..86eef25c4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/model/Download.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/model/Download.kt @@ -21,9 +21,8 @@ data class Download( val totalProgress: Int get() = pages?.sumOf(Page::progress) ?: 0 - @Volatile - @Transient - var downloadedImages: Int = 0 + val downloadedImages: Int + get() = pages?.count { it.status == Page.State.READY } ?: 0 @Volatile @Transient From 79323de3268340a2b70a7f8539b94fab5d497df1 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 25 Feb 2023 15:29:00 -0500 Subject: [PATCH 04/16] Avoid crash in DeleteLibraryMangaDialog No clue why it ever gets a -1 index though. (cherry picked from commit b12c7cf9633a9fc3a728a0ef44b5d50d621a7595) --- .../presentation/components/DeleteLibraryMangaDialog.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/components/DeleteLibraryMangaDialog.kt b/app/src/main/java/eu/kanade/presentation/components/DeleteLibraryMangaDialog.kt index 52ee61559..6d2b3b6cc 100644 --- a/app/src/main/java/eu/kanade/presentation/components/DeleteLibraryMangaDialog.kt +++ b/app/src/main/java/eu/kanade/presentation/components/DeleteLibraryMangaDialog.kt @@ -64,9 +64,11 @@ fun DeleteLibraryMangaDialog( list.forEach { state -> val onCheck = { val index = list.indexOf(state) - val mutableList = list.toMutableList() - mutableList[index] = state.next() as CheckboxState.State - list = mutableList.toList() + if (index != -1) { + val mutableList = list.toMutableList() + mutableList[index] = state.next() as CheckboxState.State + list = mutableList.toList() + } } Row( From aa2ec5940f512b50adce1244d9de5cb6a907cfed Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 25 Feb 2023 15:32:46 -0500 Subject: [PATCH 05/16] Avoid crashing in SourcePreferencesScreen if source can't be loaded (cherry picked from commit 4efca047658761e54cc7574a6e33ed681de3f40a) --- .../ui/browse/extension/details/SourcePreferencesScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt index d65d2d9bc..b71c7844f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesScreen.kt @@ -61,7 +61,7 @@ class SourcePreferencesScreen(val sourceId: Long) : Screen { Scaffold( topBar = { TopAppBar( - title = { Text(text = Injekt.get().get(sourceId)!!.toString()) }, + title = { Text(text = Injekt.get().getOrStub(sourceId).toString()) }, navigationIcon = { IconButton(onClick = navigator::pop) { Icon( From c4ab2b46753ee59f4d1fd3cf88a616c10f078940 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 5 Mar 2023 10:17:22 -0500 Subject: [PATCH 06/16] Bump default user agent string and minimum WebView version (cherry picked from commit c6e5f8abd9e0e2096d3a8ad17a370107e20cc288) --- .../main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt | 2 +- .../main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt b/core/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt index bf6b5fc1d..1fdb1d81a 100644 --- a/core/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/NetworkPreferences.kt @@ -17,6 +17,6 @@ class NetworkPreferences( } fun defaultUserAgent(): Preference { - return preferenceStore.getString("default_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0") + return preferenceStore.getString("default_user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0") } } diff --git a/core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt b/core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt index 1ab799228..beef906d7 100644 --- a/core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt @@ -12,7 +12,7 @@ import tachiyomi.core.util.system.logcat object WebViewUtil { const val SPOOF_PACKAGE_NAME = "org.chromium.chrome" - const val MINIMUM_WEBVIEW_VERSION = 105 + const val MINIMUM_WEBVIEW_VERSION = 108 fun supportsWebView(context: Context): Boolean { try { From d2dd34c2e53818718ec48f0ed9f167e4cacb8db5 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 26 Feb 2023 16:48:04 -0500 Subject: [PATCH 07/16] Use queued last chapter read number when performing delayed tracker update Fixes #8876 (cherry picked from commit f7f2072621bbcaf4ddbe07f746a5cf78490c95c9) --- .../track/service/DelayedTrackingUpdateJob.kt | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt b/app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt index 46703440a..521209c48 100644 --- a/app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt +++ b/app/src/main/java/eu/kanade/domain/track/service/DelayedTrackingUpdateJob.kt @@ -31,30 +31,33 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters) val trackManager = Injekt.get() val delayedTrackingStore = Injekt.get() - withIOContext { - val tracks = delayedTrackingStore.getItems().mapNotNull { - val track = getTracks.awaitOne(it.trackId) - if (track == null) { - delayedTrackingStore.remove(it.trackId) - } - track - } - - tracks.forEach { track -> - try { - val service = trackManager.getService(track.syncId) - if (service != null && service.isLogged) { - service.update(track.toDbTrack(), true) - insertTrack.await(track) + val results = withIOContext { + delayedTrackingStore.getItems() + .mapNotNull { + val track = getTracks.awaitOne(it.trackId) + if (track == null) { + delayedTrackingStore.remove(it.trackId) + } + track?.copy(lastChapterRead = it.lastChapterRead.toDouble()) + } + .mapNotNull { track -> + try { + val service = trackManager.getService(track.syncId) + if (service != null && service.isLogged) { + logcat(LogPriority.DEBUG) { "Updating delayed track item: ${track.id}, last chapter read: ${track.lastChapterRead}" } + service.update(track.toDbTrack(), true) + insertTrack.await(track) + } + delayedTrackingStore.remove(track.id) + null + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) + false } - delayedTrackingStore.remove(track.id) - } catch (e: Exception) { - logcat(LogPriority.ERROR, e) } - } } - return Result.success() + return if (results.isNotEmpty()) Result.failure() else Result.success() } companion object { From bf85e147e76769d124fb0ee60140d6d5db4f0daf Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 19 Mar 2023 17:14:51 -0400 Subject: [PATCH 08/16] Set default automatic library updates to off (cherry picked from commit abd23b68266a296c9698ba89f0cb665bbe9a799d) --- .../java/eu/kanade/domain/library/service/LibraryPreferences.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/eu/kanade/domain/library/service/LibraryPreferences.kt b/app/src/main/java/eu/kanade/domain/library/service/LibraryPreferences.kt index 2f3b126fe..f389609c5 100644 --- a/app/src/main/java/eu/kanade/domain/library/service/LibraryPreferences.kt +++ b/app/src/main/java/eu/kanade/domain/library/service/LibraryPreferences.kt @@ -22,7 +22,7 @@ class LibraryPreferences( fun landscapeColumns() = preferenceStore.getInt("pref_library_columns_landscape_key", 0) - fun libraryUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 24) + fun libraryUpdateInterval() = preferenceStore.getInt("pref_library_update_interval_key", 0) fun libraryUpdateLastTimestamp() = preferenceStore.getLong("library_update_last_timestamp", 0L) fun libraryUpdateDeviceRestriction() = preferenceStore.getStringSet("library_update_restriction", setOf(DEVICE_ONLY_ON_WIFI)) From 38428c6ebeba0f87f3aabe3095a1a4d8babd94bc Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 19 Mar 2023 17:23:51 -0400 Subject: [PATCH 09/16] Show proper string in manga detail screen for SourceNotInstalledException (cherry picked from commit 14d1bcacc9cba0e14cdf90a7972bf85660465c0b) --- .../kanade/tachiyomi/ui/manga/MangaScreenModel.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt index c8541988d..f6f0ba994 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt @@ -977,6 +977,14 @@ class MangaInfoScreenModel( } } } + + private val Throwable.snackbarMessage: String + get() = when (val className = this::class.simpleName) { + null -> message ?: "" + "SourceNotInstalledException" -> context.getString(R.string.loader_not_implemented_error) + "Exception", "HttpException", "IOException" -> message ?: className + else -> "$className: $message" + } } sealed class MangaScreenState { @@ -1055,10 +1063,3 @@ val chapterDecimalFormat = DecimalFormat( DecimalFormatSymbols() .apply { decimalSeparator = '.' }, ) - -private val Throwable.snackbarMessage: String - get() = when (val className = this::class.simpleName) { - null -> message ?: "" - "Exception", "HttpException", "IOException", "SourceNotInstalledException" -> message ?: className - else -> "$className: $message" - } From 934ed0551a509122d8b14005cc3d5973c442081d Mon Sep 17 00:00:00 2001 From: arkon Date: Tue, 21 Mar 2023 22:59:42 -0400 Subject: [PATCH 10/16] Bump subsampling-scale-image-view (cherry picked from commit e5e18c2030f26e89aedd5536d21ab915ccdbb26a) --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5849a33a0..249903bd0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ coil-core = { module = "io.coil-kt:coil", version.ref = "coil_version" } coil-gif = { module = "io.coil-kt:coil-gif", version.ref = "coil_version" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil_version" } -subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:846abe0" +subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:c8e2650" image-decoder = "com.github.tachiyomiorg:image-decoder:7879b45" natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1" From 10973bf3cd2d57e3a6a1323fd5f1a0dc58b472ad Mon Sep 17 00:00:00 2001 From: arkon Date: Fri, 24 Mar 2023 22:58:29 -0400 Subject: [PATCH 11/16] Fix Spanish (Latin America) being missing from in-app language selection (cherry picked from commit 290efb0283145d81290972991047064c1d905c9c) --- buildSrc/src/main/kotlin/LocalesConfigPlugin.kt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/buildSrc/src/main/kotlin/LocalesConfigPlugin.kt b/buildSrc/src/main/kotlin/LocalesConfigPlugin.kt index b1e53fde9..2c352f131 100644 --- a/buildSrc/src/main/kotlin/LocalesConfigPlugin.kt +++ b/buildSrc/src/main/kotlin/LocalesConfigPlugin.kt @@ -3,25 +3,22 @@ import org.gradle.api.Task import org.gradle.api.tasks.TaskProvider import org.gradle.kotlin.dsl.TaskContainerScope +private val emptyResourcesElement = "\\s*|".toRegex() +private val valuesPrefix = "values(-(b\\+)?)?".toRegex() + fun TaskContainerScope.registerLocalesConfigTask(project: Project): TaskProvider { return with(project) { register("generateLocalesConfig") { - val emptyResourcesElement = "\\s*|".toRegex() - val valuesPrefix = "values-?".toRegex() - val languages = fileTree("$projectDir/src/main/res/") - .matching { - include("**/strings.xml") - } - .filterNot { - it.readText().contains(emptyResourcesElement) - } + .matching { include("**/strings.xml") } + .filterNot { it.readText().contains(emptyResourcesElement) } .map { it.parentFile.name } .sorted() .joinToString(separator = "\n") { val language = it .replace(valuesPrefix, "") .replace("-r", "-") + .replace("+", "-") .takeIf(String::isNotBlank) ?: "en" " " } From 4dd67e4348b5eaf627b6594f911071f6821a46f1 Mon Sep 17 00:00:00 2001 From: arkon Date: Wed, 5 Apr 2023 22:29:56 -0400 Subject: [PATCH 12/16] Save current chapter progress when navigating to adjacent chapters Fixes #9295 (cherry picked from commit 776d36caf11cf29287e4cb86a6e64574a296f89c) --- .../tachiyomi/ui/reader/ReaderActivity.kt | 8 ++---- .../tachiyomi/ui/reader/ReaderViewModel.kt | 25 ++++++++++--------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 0d1d2ef09..dec65e761 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -99,10 +99,6 @@ import uy.kohesive.injekt.injectLazy import kotlin.math.abs import kotlin.math.max -/** - * Activity containing the reader of Tachiyomi. This activity is mostly a container of the - * viewers, to which calls from the presenter or UI events are delegated. - */ class ReaderActivity : BaseActivity() { companion object { @@ -661,7 +657,7 @@ class ReaderActivity : BaseActivity() { * Called from the presenter when a manga is ready. Used to instantiate the appropriate viewer * and the toolbar title. */ - fun setManga(manga: Manga) { + private fun setManga(manga: Manga) { val prevViewer = viewer val viewerMode = ReadingModeType.fromPreference(viewModel.getMangaReadingMode(resolveDefault = false)) @@ -776,7 +772,7 @@ class ReaderActivity : BaseActivity() { * Called from the presenter if the initial load couldn't load the pages of the chapter. In * this case the activity is closed and a toast is shown to the user. */ - fun setInitialChapterError(error: Throwable) { + private fun setInitialChapterError(error: Throwable) { logcat(LogPriority.ERROR, error) finish() toast(error.message) 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 203bcbff1..fae7f638d 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 @@ -201,17 +201,6 @@ class ReaderViewModel( private val incognitoMode = preferences.incognitoMode().get() - override fun onCleared() { - val currentChapters = state.value.viewerChapters - if (currentChapters != null) { - currentChapters.unref() - saveReadingProgress(currentChapters.currChapter) - chapterToDownload?.let { - downloadManager.addDownloadsToStartOfQueue(listOf(it)) - } - } - } - init { // To save state state.map { it.viewerChapters?.currChapter } @@ -226,6 +215,17 @@ class ReaderViewModel( .launchIn(viewModelScope) } + override fun onCleared() { + val currentChapters = state.value.viewerChapters + if (currentChapters != null) { + currentChapters.unref() + saveReadingProgress(currentChapters.currChapter) + chapterToDownload?.let { + downloadManager.addDownloadsToStartOfQueue(listOf(it)) + } + } + } + /** * Called when the user pressed the back button and is going to leave the reader. Used to * trigger deletion of the downloaded chapters. @@ -338,10 +338,11 @@ class ReaderViewModel( } /** - * Called when the user is going to load the prev/next chapter through the menu button. + * Called when the user is going to load the prev/next chapter through the toolbar buttons. */ private suspend fun loadAdjacent(chapter: ReaderChapter) { val loader = loader ?: return + saveCurrentChapterReadingProgress() logcat { "Loading adjacent ${chapter.chapter.url}" } From fd8b97fc87b1a477b61052a758716df86005e044 Mon Sep 17 00:00:00 2001 From: arkon Date: Wed, 5 Apr 2023 22:36:57 -0400 Subject: [PATCH 13/16] Better handle overflowing content in MigrateDialog actions Fixes #9207 (cherry picked from commit b7cd7b8b4e7a2f0a544f36f40b2e352286f739b2) --- .../tachiyomi/ui/browse/migration/search/MigrateDialog.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt index b0db140a5..b70fe93d4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt @@ -2,7 +2,9 @@ package eu.kanade.tachiyomi.ui.browse.migration.search import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -23,6 +25,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastForEachIndexed import cafe.adriel.voyager.core.model.StateScreenModel import eu.kanade.domain.category.interactor.SetMangaCategories @@ -111,7 +114,9 @@ internal fun MigrateDialog( } }, confirmButton = { - Row { + FlowRow( + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { TextButton( onClick = { onClickTitle() From 7115a9b9feca8a74844ca70728521f2d78a0c6f0 Mon Sep 17 00:00:00 2001 From: Eshlender <35057681+e-shl@users.noreply.github.com> Date: Sat, 15 Apr 2023 06:57:05 +0500 Subject: [PATCH 14/16] Update track domain shikimori.me (#9333) shikimori.me (cherry picked from commit 564a0980b99183bb2b73999c17a4c6603c008f05) --- .../eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt index 2d16a10dc..5340f8562 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt @@ -158,7 +158,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter private const val clientId = "1aaf4cf232372708e98b5abc813d795b539c5a916dbbfe9ac61bf02a360832cc" private const val clientSecret = "229942c742dd4cde803125d17d64501d91c0b12e14cb1e5120184d77d67024c0" - private const val baseUrl = "https://shikimori.one" + private const val baseUrl = "https://shikimori.me" private const val apiUrl = "$baseUrl/api" private const val oauthUrl = "$baseUrl/oauth/token" private const val loginUrl = "$baseUrl/oauth/authorize" From 9e09a20e65ec9952e24535f27e84249e808ac22a Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 25 Feb 2023 15:13:59 -0500 Subject: [PATCH 15/16] Avoid uncaught exceptions from OkHttp interceptors crashing entire app (cherry picked from commit 26d422b0aeaee2d0a7957f0f8d955e045dde1a34) --- .../kanade/tachiyomi/network/NetworkHelper.kt | 2 ++ .../UncaughtExceptionInterceptor.kt | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 core/src/main/java/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt diff --git a/core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt b/core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt index d81b666d6..886093daf 100644 --- a/core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt +++ b/core/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.network import android.content.Context import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor +import eu.kanade.tachiyomi.network.interceptor.UncaughtExceptionInterceptor import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor import okhttp3.Cache import okhttp3.OkHttpClient @@ -29,6 +30,7 @@ class NetworkHelper(context: Context) { .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .callTimeout(2, TimeUnit.MINUTES) + .addInterceptor(UncaughtExceptionInterceptor()) .addInterceptor(userAgentInterceptor) if (preferences.verboseLogging().get()) { diff --git a/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt new file mode 100644 index 000000000..2362b78c6 --- /dev/null +++ b/core/src/main/java/eu/kanade/tachiyomi/network/interceptor/UncaughtExceptionInterceptor.kt @@ -0,0 +1,24 @@ +package eu.kanade.tachiyomi.network.interceptor + +import okhttp3.Interceptor +import okhttp3.Response +import java.io.IOException + +/** + * Catches any uncaught exceptions from later in the chain and rethrows as a non-fatal + * IOException to avoid catastrophic failure. + * + * This should be the first interceptor in the client. + * + * See https://square.github.io/okhttp/4.x/okhttp/okhttp3/-interceptor/ + */ +class UncaughtExceptionInterceptor : Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + return try { + chain.proceed(chain.request()) + } catch (e: Exception) { + throw IOException(e) + } + } +} From c615f4d45810febb977a1412b0e6f7d95cbcb5c3 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 16 Apr 2023 11:00:14 -0400 Subject: [PATCH 16/16] Release v0.14.6 --- .github/ISSUE_TEMPLATE.md | 2 +- .github/ISSUE_TEMPLATE/report_issue.yml | 4 ++-- .github/ISSUE_TEMPLATE/request_feature.yml | 2 +- app/build.gradle.kts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 2ecec0423..15794612e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,7 +3,7 @@ I acknowledge that: - I have updated: - - To the latest version of the app (stable is v0.14.5) + - To the latest version of the app (stable is v0.14.6) - All extensions - I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/ - If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions diff --git a/.github/ISSUE_TEMPLATE/report_issue.yml b/.github/ISSUE_TEMPLATE/report_issue.yml index 0b7be7954..368f41ded 100644 --- a/.github/ISSUE_TEMPLATE/report_issue.yml +++ b/.github/ISSUE_TEMPLATE/report_issue.yml @@ -53,7 +53,7 @@ body: label: Tachiyomi version description: You can find your Tachiyomi version in **More → About**. placeholder: | - Example: "0.14.5" + Example: "0.14.6" validations: required: true @@ -98,7 +98,7 @@ body: required: true - label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/). required: true - - label: I have updated the app to version **[0.14.5](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**. + - label: I have updated the app to version **[0.14.6](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**. required: true - label: I have updated all installed extensions. required: true diff --git a/.github/ISSUE_TEMPLATE/request_feature.yml b/.github/ISSUE_TEMPLATE/request_feature.yml index 93e51ccd2..af59d3565 100644 --- a/.github/ISSUE_TEMPLATE/request_feature.yml +++ b/.github/ISSUE_TEMPLATE/request_feature.yml @@ -33,7 +33,7 @@ body: required: true - label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose). required: true - - label: I have updated the app to version **[0.14.5](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**. + - label: I have updated the app to version **[0.14.6](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**. required: true - label: I will fill out all of the requested information in this form. required: true diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9b06f69f8..95fe09172 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -22,8 +22,8 @@ android { defaultConfig { applicationId = "eu.kanade.tachiyomi" - versionCode = 98 - versionName = "0.14.5" + versionCode = 101 + versionName = "0.14.6" buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")