Update parsers
This commit is contained in:
@@ -76,7 +76,6 @@ android {
|
||||
'-opt-in=kotlin.contracts.ExperimentalContracts',
|
||||
'-opt-in=coil3.annotation.ExperimentalCoilApi',
|
||||
'-opt-in=coil3.annotation.InternalCoilApi',
|
||||
'-opt-in=org.koitharu.kotatsu.parsers.InternalParsersApi',
|
||||
'-Xjspecify-annotations=strict',
|
||||
'-Xtype-enhancement-improvements-strict-mode'
|
||||
]
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.core.network.webview
|
||||
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
class ContinuationResumeWebViewClient(
|
||||
private val continuation: Continuation<Unit>,
|
||||
) : WebViewClient() {
|
||||
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
view?.webViewClient = WebViewClient() // reset to default
|
||||
continuation.resume(Unit)
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import org.koitharu.kotatsu.core.exceptions.InteractiveActionRequiredException
|
||||
import org.koitharu.kotatsu.core.image.BitmapDecoderCompat
|
||||
import org.koitharu.kotatsu.core.network.MangaHttpClient
|
||||
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
||||
import org.koitharu.kotatsu.core.network.webview.ContinuationResumeWebViewClient
|
||||
import org.koitharu.kotatsu.core.prefs.SourceSettings
|
||||
import org.koitharu.kotatsu.core.util.ext.configureForParser
|
||||
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
|
||||
@@ -51,6 +52,7 @@ class MangaLoaderContextImpl @Inject constructor(
|
||||
private var webViewCached: WeakReference<WebView>? = null
|
||||
private val webViewUserAgent by lazy { obtainWebViewUserAgent() }
|
||||
|
||||
@Deprecated("Provide a base url")
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
override suspend fun evaluateJs(script: String): String? = withContext(Dispatchers.Main.immediate) {
|
||||
val webView = obtainWebView()
|
||||
@@ -61,6 +63,19 @@ class MangaLoaderContextImpl @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun evaluateJs(baseUrl: String, script: String): String? = withContext(Dispatchers.Main.immediate) {
|
||||
val webView = obtainWebView()
|
||||
suspendCoroutine { cont ->
|
||||
webView.webViewClient = ContinuationResumeWebViewClient(cont)
|
||||
webView.loadDataWithBaseURL(baseUrl, " ", "text/html", null, null)
|
||||
}
|
||||
suspendCoroutine { cont ->
|
||||
webView.evaluateJavascript(script) { result ->
|
||||
cont.resume(result?.takeUnless { it == "null" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDefaultUserAgent(): String = webViewUserAgent
|
||||
|
||||
override fun getConfig(source: MangaSource): MangaSourceConfig {
|
||||
|
||||
@@ -215,6 +215,7 @@ fun WebView.configureForParser(userAgentOverride: String?) = with(settings) {
|
||||
WebViewCompat.setAudioMuted(this@configureForParser, true)
|
||||
}
|
||||
databaseEnabled = true
|
||||
allowContentAccess = false
|
||||
if (userAgentOverride != null) {
|
||||
userAgentString = userAgentOverride
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.fragment.app.viewModels
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||
import org.koitharu.kotatsu.core.model.getTitle
|
||||
@@ -49,13 +50,15 @@ class SourceSettingsFragment : BasePreferenceFragment(0), Preference.OnPreferenc
|
||||
findPreference<Preference>(KEY_AUTH)?.run {
|
||||
val authProvider = (viewModel.repository as? ParserMangaRepository)?.getAuthProvider()
|
||||
isVisible = authProvider != null
|
||||
isEnabled = authProvider?.isAuthorized == false
|
||||
}
|
||||
findPreference<Preference>(SourceSettings.KEY_SLOWDOWN)?.isVisible = isValidSource
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
viewModel.isAuthorized.filterNotNull().observe(viewLifecycleOwner) { isAuthorized ->
|
||||
findPreference<Preference>(KEY_AUTH)?.isEnabled = !isAuthorized
|
||||
}
|
||||
viewModel.username.observe(viewLifecycleOwner) { username ->
|
||||
findPreference<Preference>(KEY_AUTH)?.summary = username?.let {
|
||||
getString(R.string.logged_in_as, it)
|
||||
|
||||
@@ -38,6 +38,7 @@ class SourceSettingsViewModel @Inject constructor(
|
||||
|
||||
val onActionDone = MutableEventFlow<ReversibleAction>()
|
||||
val username = MutableStateFlow<String?>(null)
|
||||
val isAuthorized = MutableStateFlow<Boolean?>(null)
|
||||
val browserUrl = MutableStateFlow<String?>(null)
|
||||
val isEnabled = mangaSourcesRepository.observeIsEnabled(source)
|
||||
private var usernameLoadJob: Job? = null
|
||||
@@ -103,6 +104,8 @@ class SourceSettingsViewModel @Inject constructor(
|
||||
launchLoadingJob(Dispatchers.Default) {
|
||||
try {
|
||||
username.value = null
|
||||
isAuthorized.value = null
|
||||
isAuthorized.value = authProvider?.isAuthorized()
|
||||
username.value = authProvider?.getUsername()
|
||||
} catch (_: AuthRequiredException) {
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.browser.BaseBrowserActivity
|
||||
@@ -20,12 +21,15 @@ import org.koitharu.kotatsu.core.parser.ParserMangaRepository
|
||||
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SourceAuthActivity : BaseBrowserActivity(), BrowserCallback {
|
||||
|
||||
private lateinit var authProvider: MangaParserAuthProvider
|
||||
|
||||
private var authCheckJob: Job? = null
|
||||
|
||||
override fun onCreate2(savedInstanceState: Bundle?, source: MangaSource, repository: ParserMangaRepository?) {
|
||||
if (repository == null) {
|
||||
finishAfterTransition()
|
||||
@@ -72,10 +76,20 @@ class SourceAuthActivity : BaseBrowserActivity(), BrowserCallback {
|
||||
|
||||
override fun onLoadingStateChanged(isLoading: Boolean) {
|
||||
super.onLoadingStateChanged(isLoading)
|
||||
if (!isLoading && authProvider.isAuthorized) {
|
||||
Toast.makeText(this, R.string.auth_complete, Toast.LENGTH_SHORT).show()
|
||||
setResult(RESULT_OK)
|
||||
finishAfterTransition()
|
||||
if (isLoading) {
|
||||
return
|
||||
}
|
||||
val prevJob = authCheckJob
|
||||
authCheckJob = lifecycleScope.launch {
|
||||
prevJob?.join()
|
||||
val isAuthorized = runCatchingCancellable {
|
||||
authProvider.isAuthorized()
|
||||
}.getOrDefault(false)
|
||||
if (isAuthorized) {
|
||||
Toast.makeText(this@SourceAuthActivity, R.string.auth_complete, Toast.LENGTH_SHORT).show()
|
||||
setResult(RESULT_OK)
|
||||
finishAfterTransition()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Preference
|
||||
android:enabled="false"
|
||||
android:key="auth"
|
||||
android:order="100"
|
||||
android:persistent="false"
|
||||
|
||||
Reference in New Issue
Block a user