From 2ae488544bb26e5c3edf21257dfec859720551b9 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sat, 25 May 2024 10:14:39 +0300 Subject: [PATCH 1/6] Fix crashes and improve predictive back support --- app/build.gradle | 1 + .../kotatsu/browser/BrowserActivity.kt | 6 ++-- .../core/parser/MangaLoaderContextImpl.kt | 15 ++++++++-- .../koitharu/kotatsu/core/ui/BaseActivity.kt | 5 ++-- .../ui/sheet/BottomSheetCollapseCallback.kt | 28 +++++++++++++++---- .../kotatsu/details/ui/DetailsActivity.kt | 5 ++-- .../kotatsu/settings/SettingsActivity.kt | 2 +- .../storage/MangaDirectorySelectDialog.kt | 9 ++++-- .../layout-w600dp-land/activity_settings.xml | 2 +- app/src/main/res/layout/activity_settings.xml | 5 ++-- 10 files changed, 56 insertions(+), 22 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e54e96c09..81ff7cb27 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -94,6 +94,7 @@ dependencies { implementation 'androidx.core:core-ktx:1.13.1' implementation 'androidx.activity:activity-ktx:1.9.0' implementation 'androidx.fragment:fragment-ktx:1.7.1' + implementation 'androidx.transition:transition-ktx:1.5.0' implementation 'androidx.collection:collection-ktx:1.4.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0' implementation 'androidx.lifecycle:lifecycle-service:2.8.0' diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt index 4698e91f5..04f71e3bd 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt @@ -108,8 +108,10 @@ class BrowserActivity : BaseActivity(), BrowserCallback override fun onDestroy() { super.onDestroy() - viewBinding.webView.stopLoading() - viewBinding.webView.destroy() + if (hasViewBinding()) { + viewBinding.webView.stopLoading() + viewBinding.webView.destroy() + } } override fun onLoadingStateChanged(isLoading: Boolean) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt index a4fe4fa25..fbea3a92c 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt @@ -16,6 +16,7 @@ import okhttp3.OkHttpClient import okhttp3.Response import okhttp3.ResponseBody.Companion.asResponseBody import okio.Buffer +import okio.IOException import org.koitharu.kotatsu.core.network.MangaHttpClient import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar import org.koitharu.kotatsu.core.prefs.SourceSettings @@ -29,6 +30,7 @@ import org.koitharu.kotatsu.parsers.bitmap.Bitmap import org.koitharu.kotatsu.parsers.config.MangaSourceConfig import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.network.UserAgents +import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import java.lang.ref.WeakReference import java.util.Locale import javax.inject.Inject @@ -75,7 +77,10 @@ class MangaLoaderContextImpl @Inject constructor( return LocaleListCompat.getAdjustedDefault().toList() } - override fun redrawImageResponse(response: Response, redraw: (image: Bitmap) -> Bitmap): Response { + override fun redrawImageResponse( + response: Response, + redraw: (image: Bitmap) -> Bitmap + ): Response = runCatchingCancellable { val image = response.requireBody().byteStream() val opts = BitmapFactory.Options() @@ -87,9 +92,15 @@ class MangaLoaderContextImpl @Inject constructor( result.compressTo(it.outputStream()) }.asResponseBody("image/jpeg".toMediaType()) - return response.newBuilder() + response.newBuilder() .body(body) .build() + }.getOrElse { error -> + if (error is IOException) { + throw error + } else { + throw IOException(error.message, error) + } } override fun createBitmap(width: Int, height: Int): Bitmap { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt index 3ebd55d8d..d66e1328b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt @@ -92,9 +92,6 @@ abstract class BaseActivity : } override fun onSupportNavigateUp(): Boolean { - if (supportFragmentManager.popBackStackImmediate()) { - return false - } dispatchNavigateUp() return true } @@ -159,6 +156,8 @@ abstract class BaseActivity : } } + protected fun hasViewBinding() = ::viewBinding.isInitialized + @EntryPoint @InstallIn(SingletonComponent::class) interface BaseActivityEntryPoint { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/sheet/BottomSheetCollapseCallback.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/sheet/BottomSheetCollapseCallback.kt index de18f7b29..ee6a25c58 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/sheet/BottomSheetCollapseCallback.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/sheet/BottomSheetCollapseCallback.kt @@ -1,22 +1,34 @@ package org.koitharu.kotatsu.core.ui.sheet +import android.annotation.SuppressLint import android.view.View +import android.view.ViewGroup +import androidx.activity.BackEventCompat import androidx.activity.OnBackPressedCallback import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HALF_EXPANDED +import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN class BottomSheetCollapseCallback( - private val behavior: BottomSheetBehavior<*>, -) : OnBackPressedCallback(behavior.state == STATE_EXPANDED) { + private val sheet: ViewGroup, + private val behavior: BottomSheetBehavior<*> = BottomSheetBehavior.from(sheet), +) : OnBackPressedCallback(behavior.state == STATE_EXPANDED || behavior.state == STATE_HALF_EXPANDED) { init { behavior.addBottomSheetCallback( object : BottomSheetBehavior.BottomSheetCallback() { + @SuppressLint("SwitchIntDef") override fun onStateChanged(view: View, state: Int) { - isEnabled = state == STATE_EXPANDED || state == STATE_HALF_EXPANDED + when (state) { + STATE_EXPANDED, + STATE_HALF_EXPANDED -> isEnabled = true + + STATE_COLLAPSED, + STATE_HIDDEN -> isEnabled = false + } } override fun onSlide(p0: View, p1: Float) = Unit @@ -24,7 +36,11 @@ class BottomSheetCollapseCallback( ) } - override fun handleOnBackPressed() { - behavior.state = STATE_COLLAPSED - } + override fun handleOnBackPressed() = behavior.handleBackInvoked() + + override fun handleOnBackCancelled() = behavior.cancelBackProgress() + + override fun handleOnBackProgressed(backEvent: BackEventCompat) = behavior.updateBackProgress(backEvent) + + override fun handleOnBackStarted(backEvent: BackEventCompat) = behavior.startBackProgress(backEvent) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 7c9dd9851..777c4ae4b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -31,7 +31,6 @@ import coil.request.ImageRequest import coil.request.SuccessResult import coil.transform.CircleCropTransformation import coil.util.CoilUtils -import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.chip.Chip import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint @@ -153,8 +152,8 @@ class DetailsActivity : viewBinding.textViewDescription.movementMethod = LinkMovementMethodCompat.getInstance() viewBinding.chipsTags.onChipClickListener = this TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView) - viewBinding.containerBottomSheet?.let { BottomSheetBehavior.from(it) }?.let { behavior -> - onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(behavior)) + viewBinding.containerBottomSheet?.let { sheet -> + onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(sheet)) } viewModel.details.filterNotNull().observe(this, ::onMangaUpdated) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt index 7a1f07c9f..b36099f34 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -125,7 +125,7 @@ class SettingsActivity : supportFragmentManager.commit { setReorderingAllowed(true) replace(R.id.container, fragment) - setTransition(FragmentTransaction.TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN) + setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) if (!isMasterDetails || (hasFragment && !isFromRoot)) { addToBackStack(null) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/MangaDirectorySelectDialog.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/MangaDirectorySelectDialog.kt index 735be10a0..f9294c3e0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/MangaDirectorySelectDialog.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/MangaDirectorySelectDialog.kt @@ -11,7 +11,6 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.FragmentManager import androidx.fragment.app.viewModels import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.snackbar.Snackbar import com.hannesdorfmann.adapterdelegates4.AsyncListDifferDelegationAdapter import dagger.hilt.android.AndroidEntryPoint import org.koitharu.kotatsu.R @@ -41,7 +40,13 @@ class MangaDirectorySelectDialog : AlertDialogFragment diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index b8698c566..897aef412 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -9,12 +9,13 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fitsSystemWindows="true"> + android:fitsSystemWindows="true" + app:liftOnScroll="false"> From 0faa97b08cb9bb264f9648366278a4745783e768 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sat, 25 May 2024 16:11:21 +0300 Subject: [PATCH 2/6] Update settings activity ui --- app/build.gradle | 4 +- .../kotatsu/settings/SettingsMenuProvider.kt | 33 ++++++++++ app/src/debug/res/menu/opt_settings.xml | 7 +- .../kotatsu/core/ui/BasePreferenceFragment.kt | 2 +- .../kotatsu/settings/RootSettingsFragment.kt | 6 ++ .../kotatsu/settings/SettingsActivity.kt | 43 ++---------- .../layout-w600dp-land/activity_settings.xml | 66 +++++++++---------- app/src/main/res/menu/opt_settings.xml | 2 - .../kotatsu/settings/SettingsMenuProvider.kt | 15 +++++ 9 files changed, 95 insertions(+), 83 deletions(-) create mode 100644 app/src/debug/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt delete mode 100644 app/src/main/res/menu/opt_settings.xml create mode 100644 app/src/release/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt diff --git a/app/build.gradle b/app/build.gradle index 81ff7cb27..ee04db19a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdk = 21 targetSdk = 34 - versionCode = 643 - versionName = '7.1' + versionCode = 644 + versionName = '7.1.1' generatedDensities = [] testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner' ksp { diff --git a/app/src/debug/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt b/app/src/debug/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt new file mode 100644 index 000000000..519db2319 --- /dev/null +++ b/app/src/debug/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt @@ -0,0 +1,33 @@ +package org.koitharu.kotatsu.settings + +import android.content.Context +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider +import leakcanary.LeakCanary +import org.koitharu.kotatsu.R +import org.koitharu.workinspector.WorkInspector + +class SettingsMenuProvider( + private val context: Context, +) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { + menuInflater.inflate(R.menu.opt_settings, menu) + } + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { + R.id.action_leaks -> { + context.startActivity(LeakCanary.newLeakDisplayActivityIntent()) + true + } + + R.id.action_works -> { + context.startActivity(WorkInspector.getIntent(context)) + true + } + + else -> false + } +} diff --git a/app/src/debug/res/menu/opt_settings.xml b/app/src/debug/res/menu/opt_settings.xml index 0ad9f78bc..b7bb4a5ac 100644 --- a/app/src/debug/res/menu/opt_settings.xml +++ b/app/src/debug/res/menu/opt_settings.xml @@ -8,14 +8,9 @@ android:title="@string/leak_canary_display_activity_label" app:showAsAction="never" /> - - diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt index aabadc67a..0a5a90c07 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt @@ -63,7 +63,7 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : ) } - protected fun setTitle(title: CharSequence?) { + protected open fun setTitle(title: CharSequence?) { (activity as? SettingsActivity)?.setSectionTitle(title) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/RootSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/RootSettingsFragment.kt index f095ec6c7..220c65bda 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/RootSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/RootSettingsFragment.kt @@ -43,6 +43,12 @@ class RootSettingsFragment : BasePreferenceFragment(0) { } } + override fun setTitle(title: CharSequence?) { + if (!resources.getBoolean(R.bool.is_tablet)) { + super.setTitle(title) + } + } + private fun bindPreferenceSummary(key: String, @StringRes vararg items: Int) { findPreference(key)?.summary = items.joinToString { getString(it) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt index b36099f34..f9ae0f40d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -1,11 +1,8 @@ package org.koitharu.kotatsu.settings -import android.content.ComponentName import android.content.Context import android.content.Intent import android.os.Bundle -import android.view.Menu -import android.view.MenuItem import android.view.ViewGroup.MarginLayoutParams import androidx.core.graphics.Insets import androidx.core.view.updateLayoutParams @@ -44,9 +41,12 @@ class SettingsActivity : private val isMasterDetails get() = viewBinding.containerMaster != null + private var screenPadding = 0 + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivitySettingsBinding.inflate(layoutInflater)) + screenPadding = resources.getDimensionPixelOffset(R.dimen.screen_padding) supportActionBar?.setDisplayHomeAsUpEnabled(true) val fm = supportFragmentManager val currentFragment = fm.findFragmentById(R.id.container) @@ -59,38 +59,7 @@ class SettingsActivity : replace(R.id.container_master, RootSettingsFragment()) } } - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - super.onCreateOptionsMenu(menu) - menuInflater.inflate(R.menu.opt_settings, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { - R.id.action_leaks -> { - val intent = Intent() - intent.component = ComponentName(this, "leakcanary.internal.activity.LeakActivity") - intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP - startActivity(intent) - true - } - - R.id.action_tracker -> { - val intent = Intent() - intent.component = ComponentName(this, "org.koitharu.kotatsu.tracker.ui.debug.TrackerDebugActivity") - startActivity(intent) - true - } - - R.id.action_works -> { - val intent = Intent() - intent.component = ComponentName(this, "org.koitharu.workinspector.WorkInspectorActivity") - startActivity(intent) - true - } - - else -> super.onOptionsItemSelected(item) + addMenuProvider(SettingsMenuProvider(this)) } override fun onPreferenceStartFragment( @@ -109,8 +78,8 @@ class SettingsActivity : left = insets.left, right = insets.right, ) - viewBinding.cardDetails?.updateLayoutParams { - bottomMargin = marginStart + insets.bottom + viewBinding.textViewHeader?.updateLayoutParams { + topMargin = screenPadding + insets.top } } diff --git a/app/src/main/res/layout-w600dp-land/activity_settings.xml b/app/src/main/res/layout-w600dp-land/activity_settings.xml index 31a7ed000..4b3d15d9e 100644 --- a/app/src/main/res/layout-w600dp-land/activity_settings.xml +++ b/app/src/main/res/layout-w600dp-land/activity_settings.xml @@ -13,7 +13,7 @@ android:elevation="0dp" android:fitsSystemWindows="true" app:elevation="0dp" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toEndOf="@id/container_master" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:liftOnScroll="false"> @@ -30,50 +30,46 @@ android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/card_details" + app:layout_constraintEnd_toStartOf="@id/container" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/appbar" app:layout_constraintWidth_max="400dp" app:layout_constraintWidth_min="320dp" - app:layout_constraintWidth_percent="0.35" /> + app:layout_constraintWidth_percent="0.4" /> + + - + app:layout_constraintTop_toBottomOf="@id/textView_header" + tools:layout="@layout/fragment_settings_sources" /> - - - - - - - - - + diff --git a/app/src/main/res/menu/opt_settings.xml b/app/src/main/res/menu/opt_settings.xml deleted file mode 100644 index 1fe7aa6d4..000000000 --- a/app/src/main/res/menu/opt_settings.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/release/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt b/app/src/release/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt new file mode 100644 index 000000000..e9cc4b9a5 --- /dev/null +++ b/app/src/release/kotlin/org/koitharu/kotatsu/settings/SettingsMenuProvider.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.settings + +import android.content.Context +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import androidx.core.view.MenuProvider + +@Suppress("UNUSED_PARAMETER") +class SettingsMenuProvider(context: Context) : MenuProvider { + + override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) = Unit + + override fun onMenuItemSelected(menuItem: MenuItem): Boolean = false +} From da61462d792caecaa16f44f298e307f787e031bf Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sat, 25 May 2024 17:17:30 +0300 Subject: [PATCH 3/6] Update parsers --- app/build.gradle | 2 +- .../core/network/CommonHeadersInterceptor.kt | 22 +++++++++++++++---- .../core/parser/MangaLoaderContextImpl.kt | 15 ++----------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ee04db19a..968972860 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -82,7 +82,7 @@ afterEvaluate { } dependencies { //noinspection GradleDependency - implementation('com.github.KotatsuApp:kotatsu-parsers:d218ad5a67') { + implementation('com.github.KotatsuApp:kotatsu-parsers:51da0b62c1') { exclude group: 'org.json', module: 'json' } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt index 0b209ce2f..26e4dc212 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt @@ -4,8 +4,10 @@ import android.util.Log import dagger.Lazy import okhttp3.Headers import okhttp3.Interceptor +import okhttp3.Interceptor.Chain import okhttp3.Request import okhttp3.Response +import okio.IOException import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.parser.MangaLoaderContextImpl import org.koitharu.kotatsu.core.parser.MangaRepository @@ -13,6 +15,7 @@ import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.util.mergeWith +import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import java.net.IDN import javax.inject.Inject import javax.inject.Singleton @@ -23,7 +26,7 @@ class CommonHeadersInterceptor @Inject constructor( private val mangaLoaderContextLazy: Lazy, ) : Interceptor { - override fun intercept(chain: Interceptor.Chain): Response { + override fun intercept(chain: Chain): Response { val request = chain.request() val source = request.tag(MangaSource::class.java) val repository = if (source != null) { @@ -46,7 +49,7 @@ class CommonHeadersInterceptor @Inject constructor( headersBuilder.trySet(CommonHeaders.REFERER, "https://$idn/") } val newRequest = request.newBuilder().headers(headersBuilder.build()).build() - return repository?.intercept(ProxyChain(chain, newRequest)) ?: chain.proceed(newRequest) + return repository?.interceptSafe(ProxyChain(chain, newRequest)) ?: chain.proceed(newRequest) } private fun Headers.Builder.trySet(name: String, value: String) = try { @@ -55,10 +58,21 @@ class CommonHeadersInterceptor @Inject constructor( e.printStackTraceDebug() } + private fun Interceptor.interceptSafe(chain: Chain): Response = runCatchingCancellable { + intercept(chain) + }.getOrElse { e -> + if (e is IOException) { + throw e + } else { + // only IOException can be safely thrown from an Interceptor + throw IOException("Error in interceptor: ${e.message}", e) + } + } + private class ProxyChain( - private val delegate: Interceptor.Chain, + private val delegate: Chain, private val request: Request, - ) : Interceptor.Chain by delegate { + ) : Chain by delegate { override fun request(): Request = request } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt index fbea3a92c..a4fe4fa25 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/MangaLoaderContextImpl.kt @@ -16,7 +16,6 @@ import okhttp3.OkHttpClient import okhttp3.Response import okhttp3.ResponseBody.Companion.asResponseBody import okio.Buffer -import okio.IOException import org.koitharu.kotatsu.core.network.MangaHttpClient import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar import org.koitharu.kotatsu.core.prefs.SourceSettings @@ -30,7 +29,6 @@ import org.koitharu.kotatsu.parsers.bitmap.Bitmap import org.koitharu.kotatsu.parsers.config.MangaSourceConfig import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.network.UserAgents -import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import java.lang.ref.WeakReference import java.util.Locale import javax.inject.Inject @@ -77,10 +75,7 @@ class MangaLoaderContextImpl @Inject constructor( return LocaleListCompat.getAdjustedDefault().toList() } - override fun redrawImageResponse( - response: Response, - redraw: (image: Bitmap) -> Bitmap - ): Response = runCatchingCancellable { + override fun redrawImageResponse(response: Response, redraw: (image: Bitmap) -> Bitmap): Response { val image = response.requireBody().byteStream() val opts = BitmapFactory.Options() @@ -92,15 +87,9 @@ class MangaLoaderContextImpl @Inject constructor( result.compressTo(it.outputStream()) }.asResponseBody("image/jpeg".toMediaType()) - response.newBuilder() + return response.newBuilder() .body(body) .build() - }.getOrElse { error -> - if (error is IOException) { - throw error - } else { - throw IOException(error.message, error) - } } override fun createBitmap(width: Int, height: Int): Bitmap { From 250136cfdc8c61b5a41ccc66eb0024f568a5173b Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 27 May 2024 13:55:38 +0300 Subject: [PATCH 4/6] Update parsers --- app/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 968972860..4dda79e66 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdk = 21 targetSdk = 34 - versionCode = 644 - versionName = '7.1.1' + versionCode = 645 + versionName = '7.1.2' generatedDensities = [] testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner' ksp { @@ -82,7 +82,7 @@ afterEvaluate { } dependencies { //noinspection GradleDependency - implementation('com.github.KotatsuApp:kotatsu-parsers:51da0b62c1') { + implementation('com.github.KotatsuApp:kotatsu-parsers:26be293f24') { exclude group: 'org.json', module: 'json' } From a47fea02d13005ca948720e594800d4c565f4bb5 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 27 May 2024 14:06:56 +0300 Subject: [PATCH 5/6] Update issue templates --- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/ISSUE_TEMPLATE/report_bug.yml | 4 ++-- .github/ISSUE_TEMPLATE/request_feature.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 9af821d54..a4e64f445 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,4 +2,4 @@ blank_issues_enabled: false contact_links: - name: ⚠️ Source issue url: https://github.com/KotatsuApp/kotatsu-parsers/issues/new - about: If you have troubles with a manga parser or want to propose new manga source, please open an issue in the kotatsu-parsers repository instead \ No newline at end of file + about: If you have a problem with a specific **manga source** or want to propose a new one, please open an issue in the kotatsu-parsers repository instead diff --git a/.github/ISSUE_TEMPLATE/report_bug.yml b/.github/ISSUE_TEMPLATE/report_bug.yml index 26ef27e7f..f2a5a5b4d 100644 --- a/.github/ISSUE_TEMPLATE/report_bug.yml +++ b/.github/ISSUE_TEMPLATE/report_bug.yml @@ -60,7 +60,7 @@ body: attributes: label: Acknowledgements options: - - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue. + - label: This is not a duplicate of an existing issue. Please look through the list of [open issues](https://github.com/KotatsuApp/Kotatsu/issues) before creating a new one. required: true - - label: If this is an issue with a parser, I should be opening an issue in the [parsers repository](https://github.com/KotatsuApp/kotatsu-parsers/issues/new/choose). + - label: This is not an issue with a specific manga source. Otherwise, you have to open an issue in the [parsers repository](https://github.com/KotatsuApp/kotatsu-parsers/issues/new/choose). required: true diff --git a/.github/ISSUE_TEMPLATE/request_feature.yml b/.github/ISSUE_TEMPLATE/request_feature.yml index a8539d394..a1dab7e18 100644 --- a/.github/ISSUE_TEMPLATE/request_feature.yml +++ b/.github/ISSUE_TEMPLATE/request_feature.yml @@ -20,5 +20,5 @@ body: label: Acknowledgements description: Read this carefully, we will close and ignore your issue if you skimmed through this. options: - - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue. - required: true \ No newline at end of file + - label: This is not a duplicate of an existing issue. Please look through the list of [open issues](https://github.com/KotatsuApp/Kotatsu/issues) before creating a new one. + required: true From fddbf35e8cc0658142374151b3d1009f7eb1c776 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Mon, 27 May 2024 15:53:41 +0300 Subject: [PATCH 6/6] Fix up navigation button behavior --- .../org/koitharu/kotatsu/core/ui/BaseActivity.kt | 16 +++++++++++++++- .../koitharu/kotatsu/tracker/domain/Tracker.kt | 4 ---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt index d66e1328b..26f0214f4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt @@ -3,6 +3,7 @@ package org.koitharu.kotatsu.core.ui import android.content.Intent import android.content.res.Configuration import android.graphics.Color +import android.os.Build import android.os.Bundle import android.view.KeyEvent import android.view.View @@ -92,7 +93,20 @@ abstract class BaseActivity : } override fun onSupportNavigateUp(): Boolean { - dispatchNavigateUp() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + // TODO fix behavior on Android 14 + dispatchNavigateUp() + return true + } + val fm = supportFragmentManager + if (fm.isStateSaved) { + return false + } + if (fm.backStackEntryCount > 0) { + fm.popBackStack() + } else { + dispatchNavigateUp() + } return true } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/domain/Tracker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/domain/Tracker.kt index 49f36de9e..9b19ea0ff 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/domain/Tracker.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/domain/Tracker.kt @@ -30,10 +30,6 @@ class Tracker @Inject constructor( return repository.getTracks(offset = 0, limit = limit) } - suspend fun gc() { - repository.gc() - } - suspend fun fetchUpdates( track: MangaTracking, commit: Boolean