Fix crashes
This commit is contained in:
@@ -14,8 +14,8 @@ android {
|
||||
applicationId 'org.koitharu.kotatsu'
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 32
|
||||
versionCode 423
|
||||
versionName '3.4.11'
|
||||
versionCode 424
|
||||
versionName '3.4.12'
|
||||
generatedDensities = []
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -119,8 +119,8 @@ dependencies {
|
||||
implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0'
|
||||
implementation 'com.github.solkin:disk-lru-cache:1.4'
|
||||
|
||||
implementation 'ch.acra:acra-mail:5.9.5'
|
||||
implementation 'ch.acra:acra-dialog:5.9.5'
|
||||
implementation 'ch.acra:acra-mail:5.9.6'
|
||||
implementation 'ch.acra:acra-dialog:5.9.6'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
|
||||
|
||||
|
||||
4
app/proguard-rules.pro
vendored
4
app/proguard-rules.pro
vendored
@@ -10,4 +10,6 @@
|
||||
}
|
||||
-keep public class ** extends org.koitharu.kotatsu.base.ui.BaseFragment
|
||||
-keep class org.koitharu.kotatsu.core.db.entity.* { *; }
|
||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||
-keep class org.koitharu.kotatsu.core.exceptions.* { *; }
|
||||
-keep class org.koitharu.kotatsu.settings.NotificationSettingsLegacyFragment
|
||||
@@ -25,7 +25,7 @@ class CloudFlareDialog : AlertDialogFragment<FragmentCloudflareBinding>(), Cloud
|
||||
|
||||
override fun onInflateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?
|
||||
container: ViewGroup?,
|
||||
) = FragmentCloudflareBinding.inflate(inflater, container, false)
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@@ -49,6 +49,7 @@ class CloudFlareDialog : AlertDialogFragment<FragmentCloudflareBinding>(), Cloud
|
||||
|
||||
override fun onDestroyView() {
|
||||
binding.webView.stopLoading()
|
||||
binding.webView.destroy()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ class CloudFlareDialog : AlertDialogFragment<FragmentCloudflareBinding>(), Cloud
|
||||
|
||||
override fun onCheckPassed() {
|
||||
pendingResult.putBoolean(EXTRA_RESULT, true)
|
||||
dismiss()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.koitharu.kotatsu.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.preference.Preference
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -47,7 +49,7 @@ class SourceSettingsFragment : BasePreferenceFragment(0) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
findPreference<Preference>(KEY_AUTH)?.run {
|
||||
if (isVisible) {
|
||||
loadUsername(this)
|
||||
loadUsername(viewLifecycleOwner, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +64,7 @@ class SourceSettingsFragment : BasePreferenceFragment(0) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadUsername(preference: Preference) = viewLifecycleScope.launch {
|
||||
private fun loadUsername(owner: LifecycleOwner, preference: Preference) = owner.lifecycleScope.launch {
|
||||
runCatching {
|
||||
preference.summary = null
|
||||
withContext(Dispatchers.Default) {
|
||||
@@ -89,11 +91,12 @@ class SourceSettingsFragment : BasePreferenceFragment(0) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveError(error: Throwable): Unit {
|
||||
private fun resolveError(error: Throwable) {
|
||||
viewLifecycleScope.launch {
|
||||
if (exceptionResolver.resolve(error)) {
|
||||
val pref = findPreference<Preference>(KEY_AUTH) ?: return@launch
|
||||
loadUsername(pref)
|
||||
val lifecycleOwner = awaitViewLifecycle()
|
||||
loadUsername(lifecycleOwner, pref)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import coil.request.ImageResult
|
||||
import coil.request.SuccessResult
|
||||
import coil.util.CoilUtils
|
||||
import com.google.android.material.progressindicator.BaseProgressIndicator
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||
import org.koitharu.kotatsu.utils.progress.ImageRequestIndicatorListener
|
||||
|
||||
@@ -45,9 +46,28 @@ fun ImageResult.toBitmapOrNull() = when (this) {
|
||||
}
|
||||
|
||||
fun ImageRequest.Builder.referer(referer: String): ImageRequest.Builder {
|
||||
return setHeader(CommonHeaders.REFERER, referer)
|
||||
if (referer.isEmpty()) {
|
||||
return this
|
||||
}
|
||||
try {
|
||||
setHeader(CommonHeaders.REFERER, referer)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
val baseUrl = referer.baseUrl()
|
||||
if (baseUrl != null) {
|
||||
setHeader(CommonHeaders.REFERER, baseUrl)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun ImageRequest.Builder.indicator(indicator: BaseProgressIndicator<*>): ImageRequest.Builder {
|
||||
return listener(ImageRequestIndicatorListener(indicator))
|
||||
}
|
||||
|
||||
private fun String.baseUrl(): String? {
|
||||
return (this.toHttpUrlOrNull()?.newBuilder("/") ?: return null)
|
||||
.username("")
|
||||
.password("")
|
||||
.build()
|
||||
.toString()
|
||||
}
|
||||
@@ -7,8 +7,12 @@ import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import java.io.Serializable
|
||||
import kotlin.coroutines.resume
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
|
||||
inline fun <T : Fragment> T.withArgs(size: Int, block: Bundle.() -> Unit): T {
|
||||
val b = Bundle(size)
|
||||
@@ -49,4 +53,20 @@ fun DialogFragment.showAllowStateLoss(manager: FragmentManager, tag: String?) {
|
||||
|
||||
fun Fragment.addMenuProvider(provider: MenuProvider) {
|
||||
requireActivity().addMenuProvider(provider, viewLifecycleOwner, Lifecycle.State.RESUMED)
|
||||
}
|
||||
|
||||
suspend fun Fragment.awaitViewLifecycle(): LifecycleOwner = suspendCancellableCoroutine { cont ->
|
||||
val liveData = viewLifecycleOwnerLiveData
|
||||
val observer = object : Observer<LifecycleOwner> {
|
||||
override fun onChanged(result: LifecycleOwner?) {
|
||||
if (result != null) {
|
||||
liveData.removeObserver(this)
|
||||
cont.resume(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
liveData.observeForever(observer)
|
||||
cont.invokeOnCancellation {
|
||||
liveData.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user