Merge branch 'master' into devel
This commit is contained in:
1
app/proguard-rules.pro
vendored
1
app/proguard-rules.pro
vendored
@@ -13,3 +13,4 @@
|
||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||
|
||||
-keep class org.koitharu.kotatsu.core.exceptions.* { *; }
|
||||
-keep class org.koitharu.kotatsu.settings.NotificationSettingsLegacyFragment
|
||||
|
||||
@@ -55,6 +55,7 @@ class CloudFlareDialog : AlertDialogFragment<FragmentCloudflareBinding>(), Cloud
|
||||
|
||||
override fun onDestroyView() {
|
||||
binding.webView.stopLoading()
|
||||
binding.webView.destroy()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
@@ -83,7 +84,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 dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -53,7 +55,7 @@ class SourceSettingsFragment : BasePreferenceFragment(0) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
findPreference<Preference>(KEY_AUTH)?.run {
|
||||
if (isVisible) {
|
||||
loadUsername(this)
|
||||
loadUsername(viewLifecycleOwner, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,7 +70,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) {
|
||||
@@ -99,7 +101,8 @@ class SourceSettingsFragment : BasePreferenceFragment(0) {
|
||||
viewLifecycleScope.launch {
|
||||
if (exceptionResolver.resolve(error)) {
|
||||
val pref = findPreference<Preference>(KEY_AUTH) ?: return@launch
|
||||
loadUsername(pref)
|
||||
val lifecycleOwner = awaitViewLifecycle()
|
||||
loadUsername(lifecycleOwner, pref)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,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.R
|
||||
import org.koitharu.kotatsu.core.network.CommonHeaders
|
||||
import org.koitharu.kotatsu.utils.progress.ImageRequestIndicatorListener
|
||||
@@ -47,7 +48,18 @@ 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 {
|
||||
@@ -63,3 +75,11 @@ fun ImageRequest.Builder.crossfade(context: Context?): ImageRequest.Builder {
|
||||
val duration = context.resources.getInteger(R.integer.config_defaultAnimTime) * context.animatorDurationScale
|
||||
return crossfade(duration.toInt())
|
||||
}
|
||||
|
||||
private fun String.baseUrl(): String? {
|
||||
return (this.toHttpUrlOrNull()?.newBuilder("/") ?: return null)
|
||||
.username("")
|
||||
.password("")
|
||||
.build()
|
||||
.toString()
|
||||
}
|
||||
|
||||
@@ -6,8 +6,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)
|
||||
@@ -22,7 +26,7 @@ val Fragment.viewLifecycleScope
|
||||
fun <T : Serializable> Fragment.serializableArgument(name: String): Lazy<T> {
|
||||
return lazy(LazyThreadSafetyMode.NONE) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
requireNotNull(arguments?.getSerializable(name)) {
|
||||
requireNotNull(arguments?.getSerializableCompat(name)) {
|
||||
"No argument $name passed into ${javaClass.simpleName}"
|
||||
} as T
|
||||
}
|
||||
@@ -41,3 +45,19 @@ fun DialogFragment.showAllowStateLoss(manager: FragmentManager, tag: String?) {
|
||||
fun Fragment.addMenuProvider(provider: MenuProvider) {
|
||||
requireActivity().addMenuProvider(provider, viewLifecycleOwner, Lifecycle.State.STARTED)
|
||||
}
|
||||
|
||||
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