Fix some authorization issues
parent
2947cd3038
commit
3aed24fb49
@ -1,40 +1,71 @@
|
|||||||
package org.koitharu.kotatsu.core.exceptions.resolve
|
package org.koitharu.kotatsu.core.exceptions.resolve
|
||||||
|
|
||||||
import android.util.ArrayMap
|
import android.util.ArrayMap
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.activity.result.ActivityResultCallback
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import org.koitharu.kotatsu.browser.cloudflare.CloudFlareDialog
|
import org.koitharu.kotatsu.browser.cloudflare.CloudFlareDialog
|
||||||
import org.koitharu.kotatsu.core.exceptions.AuthRequiredException
|
import org.koitharu.kotatsu.core.exceptions.AuthRequiredException
|
||||||
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity
|
||||||
|
import org.koitharu.kotatsu.utils.TaggedActivityResult
|
||||||
|
import org.koitharu.kotatsu.utils.isSuccess
|
||||||
import kotlin.coroutines.Continuation
|
import kotlin.coroutines.Continuation
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
class ExceptionResolver(
|
class ExceptionResolver private constructor(
|
||||||
private val lifecycleOwner: LifecycleOwner,
|
private val activity: FragmentActivity?,
|
||||||
private val fm: FragmentManager
|
private val fragment: Fragment?,
|
||||||
) {
|
): ActivityResultCallback<TaggedActivityResult> {
|
||||||
|
|
||||||
private val continuations = ArrayMap<String, Continuation<Boolean>>(1)
|
private val continuations = ArrayMap<String, Continuation<Boolean>>(1)
|
||||||
|
private lateinit var sourceAuthContract: ActivityResultLauncher<MangaSource>
|
||||||
|
|
||||||
|
constructor(activity: FragmentActivity) : this(activity = activity, fragment = null) {
|
||||||
|
sourceAuthContract = activity.registerForActivityResult(SourceAuthActivity.Contract(), this)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(fragment: Fragment) : this(activity = null, fragment = fragment) {
|
||||||
|
sourceAuthContract = fragment.registerForActivityResult(SourceAuthActivity.Contract(), this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(result: TaggedActivityResult?) {
|
||||||
|
result ?: return
|
||||||
|
continuations.remove(result.tag)?.resume(result.isSuccess)
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun resolve(e: ResolvableException): Boolean = when (e) {
|
suspend fun resolve(e: ResolvableException): Boolean = when (e) {
|
||||||
is CloudFlareProtectedException -> resolveCF(e.url)
|
is CloudFlareProtectedException -> resolveCF(e.url)
|
||||||
is AuthRequiredException -> false //TODO
|
is AuthRequiredException -> resolveAuthException(e.source)
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun resolveCF(url: String) = suspendCancellableCoroutine<Boolean> { cont ->
|
private suspend fun resolveCF(url: String): Boolean {
|
||||||
val dialog = CloudFlareDialog.newInstance(url)
|
val dialog = CloudFlareDialog.newInstance(url)
|
||||||
fm.clearFragmentResult(CloudFlareDialog.TAG)
|
val fm = getFragmentManager()
|
||||||
continuations[CloudFlareDialog.TAG] = cont
|
return suspendCancellableCoroutine { cont ->
|
||||||
fm.setFragmentResultListener(CloudFlareDialog.TAG, lifecycleOwner) { key, result ->
|
fm.clearFragmentResult(CloudFlareDialog.TAG)
|
||||||
continuations.remove(key)?.resume(result.getBoolean(CloudFlareDialog.EXTRA_RESULT))
|
continuations[CloudFlareDialog.TAG] = cont
|
||||||
}
|
fm.setFragmentResultListener(CloudFlareDialog.TAG, checkNotNull(fragment ?: activity)) { key, result ->
|
||||||
dialog.show(fm, CloudFlareDialog.TAG)
|
continuations.remove(key)?.resume(result.getBoolean(CloudFlareDialog.EXTRA_RESULT))
|
||||||
cont.invokeOnCancellation {
|
}
|
||||||
continuations.remove(CloudFlareDialog.TAG, cont)
|
dialog.show(fm, CloudFlareDialog.TAG)
|
||||||
fm.clearFragmentResultListener(CloudFlareDialog.TAG)
|
cont.invokeOnCancellation {
|
||||||
dialog.dismiss()
|
continuations.remove(CloudFlareDialog.TAG, cont)
|
||||||
|
fm.clearFragmentResultListener(CloudFlareDialog.TAG)
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun resolveAuthException(source: MangaSource): Boolean = suspendCoroutine { cont ->
|
||||||
|
continuations[SourceAuthActivity.TAG] = cont
|
||||||
|
sourceAuthContract.launch(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFragmentManager() = checkNotNull(fragment?.childFragmentManager ?: activity?.supportFragmentManager)
|
||||||
}
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package org.koitharu.kotatsu.utils
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
|
||||||
|
class TaggedActivityResult(
|
||||||
|
val tag: String,
|
||||||
|
val result: Int,
|
||||||
|
)
|
||||||
|
|
||||||
|
val TaggedActivityResult.isSuccess: Boolean
|
||||||
|
get() = this.result == Activity.RESULT_OK
|
||||||
Loading…
Reference in New Issue