@ -1,36 +1,48 @@
package org.koitharu.kotatsu.core.exceptions.resolve
import android.content.Context
import android.widget.Toast
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.StringRes
import androidx.collection. Array Map
import androidx.collection. MutableScatter Map
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.EntryPointAccessors
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.alternatives.ui.AlternativesActivity
import org.koitharu.kotatsu.browser.BrowserActivity
import org.koitharu.kotatsu.browser.cloudflare.CloudFlareActivity
import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException
import org.koitharu.kotatsu.core.exceptions.UnsupportedSourceException
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BaseActivity.BaseActivityEntryPoint
import org.koitharu.kotatsu.core.ui.dialog.ErrorDetailsDialog
import org.koitharu.kotatsu.core.util.TaggedActivityResult
import org.koitharu.kotatsu.core.util.ext.findActivity
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
import org.koitharu.kotatsu.parsers.exception.NotFoundException
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.settings.sources.auth.SourceAuthActivity
import java.security.cert.CertPathValidatorException
import javax.net.ssl.SSLException
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class ExceptionResolver : ActivityResultCallback < TaggedActivityResult > {
private val continuations = Array Map< String , Continuation < Boolean > > ( 1 )
private val continuations = MutableScatter Map< String , Continuation < Boolean > > ( 1 )
private val activity : FragmentActivity ?
private val fragment : Fragment ?
private val sourceAuthContract : ActivityResultLauncher < MangaSource >
private val cloudflareContract : ActivityResultLauncher < CloudFlareProtectedException >
val context : Context ?
get ( ) = activity ?: fragment ?. context
constructor ( activity : FragmentActivity ) {
this . activity = activity
fragment = null
@ -56,6 +68,12 @@ class ExceptionResolver : ActivityResultCallback<TaggedActivityResult> {
suspend fun resolve ( e : Throwable ) : Boolean = when ( e ) {
is CloudFlareProtectedException -> resolveCF ( e )
is AuthRequiredException -> resolveAuthException ( e . source )
is SSLException ,
is CertPathValidatorException -> {
showSslErrorDialog ( )
false
}
is NotFoundException -> {
openInBrowser ( e . url )
false
@ -80,13 +98,37 @@ class ExceptionResolver : ActivityResultCallback<TaggedActivityResult> {
}
private fun openInBrowser ( url : String ) {
val context = activity ?: fragment ?. activity ?: return
context . startActivity ( BrowserActivity . newIntent ( context , url , null , null ) )
context ?. run {
startActivity ( BrowserActivity . newIntent ( this , url , null , null ) )
}
}
private fun openAlternatives ( manga : Manga ) {
val context = activity ?: fragment ?. activity ?: return
context . startActivity ( AlternativesActivity . newIntent ( context , manga ) )
context ?. run {
startActivity ( AlternativesActivity . newIntent ( this , manga ) )
}
}
private fun showSslErrorDialog ( ) {
val ctx = context ?: return
val settings = getAppSettings ( ctx )
if ( settings . isSSLBypassEnabled ) {
Toast . makeText ( ctx , R . string . operation _not _supported , Toast . LENGTH _SHORT ) . show ( )
return
}
MaterialAlertDialogBuilder ( ctx )
. setTitle ( R . string . ignore _ssl _errors )
. setMessage ( R . string . ignore _ssl _errors _summary )
. setPositiveButton ( R . string . apply ) { _ , _ ->
settings . isSSLBypassEnabled = true
Toast . makeText ( ctx , R . string . settings _apply _restart _required , Toast . LENGTH _SHORT ) . show ( )
ctx . findActivity ( ) ?. finishAffinity ( )
} . setNegativeButton ( android . R . string . cancel , null )
. show ( )
}
private fun getAppSettings ( context : Context ) : AppSettings {
return EntryPointAccessors . fromApplication < BaseActivityEntryPoint > ( context ) . settings
}
private fun getFragmentManager ( ) = checkNotNull ( fragment ?. childFragmentManager ?: activity ?. supportFragmentManager )
@ -99,6 +141,9 @@ class ExceptionResolver : ActivityResultCallback<TaggedActivityResult> {
is AuthRequiredException -> R . string . sign _in
is NotFoundException -> if ( e . url . isNotEmpty ( ) ) R . string . open _in _browser else 0
is UnsupportedSourceException -> if ( e . manga != null ) R . string . alternatives else 0
is SSLException ,
is CertPathValidatorException -> R . string . fix
else -> 0
}