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">