|
@@ -4,8 +4,9 @@ import android.content.pm.ApplicationInfo
|
|
import android.graphics.Bitmap
|
|
import android.graphics.Bitmap
|
|
import android.webkit.WebResourceRequest
|
|
import android.webkit.WebResourceRequest
|
|
import android.webkit.WebView
|
|
import android.webkit.WebView
|
|
|
|
+import androidx.compose.foundation.clickable
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.Box
|
|
-import androidx.compose.foundation.layout.fillMaxSize
|
|
|
|
|
|
+import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.Icons
|
|
@@ -17,9 +18,11 @@ import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.remember
|
|
import androidx.compose.runtime.remember
|
|
|
|
+import androidx.compose.runtime.rememberCoroutineScope
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.runtime.setValue
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.Modifier
|
|
|
|
+import androidx.compose.ui.platform.LocalUriHandler
|
|
import androidx.compose.ui.res.stringResource
|
|
import androidx.compose.ui.res.stringResource
|
|
import com.google.accompanist.web.AccompanistWebViewClient
|
|
import com.google.accompanist.web.AccompanistWebViewClient
|
|
import com.google.accompanist.web.LoadingState
|
|
import com.google.accompanist.web.LoadingState
|
|
@@ -28,9 +31,12 @@ import com.google.accompanist.web.rememberWebViewNavigator
|
|
import com.google.accompanist.web.rememberWebViewState
|
|
import com.google.accompanist.web.rememberWebViewState
|
|
import eu.kanade.presentation.components.AppBar
|
|
import eu.kanade.presentation.components.AppBar
|
|
import eu.kanade.presentation.components.AppBarActions
|
|
import eu.kanade.presentation.components.AppBarActions
|
|
|
|
+import eu.kanade.presentation.components.WarningBanner
|
|
import eu.kanade.tachiyomi.BuildConfig
|
|
import eu.kanade.tachiyomi.BuildConfig
|
|
import eu.kanade.tachiyomi.R
|
|
import eu.kanade.tachiyomi.R
|
|
|
|
+import eu.kanade.tachiyomi.util.system.getHtml
|
|
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
|
import eu.kanade.tachiyomi.util.system.setDefaultSettings
|
|
|
|
+import kotlinx.coroutines.launch
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
|
|
|
|
|
@Composable
|
|
@Composable
|
|
@@ -46,7 +52,53 @@ fun WebViewScreenContent(
|
|
) {
|
|
) {
|
|
val state = rememberWebViewState(url = url, additionalHttpHeaders = headers)
|
|
val state = rememberWebViewState(url = url, additionalHttpHeaders = headers)
|
|
val navigator = rememberWebViewNavigator()
|
|
val navigator = rememberWebViewNavigator()
|
|
|
|
+ val uriHandler = LocalUriHandler.current
|
|
|
|
+ val scope = rememberCoroutineScope()
|
|
|
|
+
|
|
var currentUrl by remember { mutableStateOf(url) }
|
|
var currentUrl by remember { mutableStateOf(url) }
|
|
|
|
+ var showCloudflareHelp by remember { mutableStateOf(false) }
|
|
|
|
+
|
|
|
|
+ val webClient = remember {
|
|
|
|
+ object : AccompanistWebViewClient() {
|
|
|
|
+ override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
|
|
|
|
+ super.onPageStarted(view, url, favicon)
|
|
|
|
+ url?.let {
|
|
|
|
+ currentUrl = it
|
|
|
|
+ onUrlChange(it)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun onPageFinished(view: WebView, url: String?) {
|
|
|
|
+ super.onPageFinished(view, url)
|
|
|
|
+ scope.launch {
|
|
|
|
+ val html = view.getHtml()
|
|
|
|
+ showCloudflareHelp = "Checking if the site connection is secure" in html
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun doUpdateVisitedHistory(
|
|
|
|
+ view: WebView,
|
|
|
|
+ url: String?,
|
|
|
|
+ isReload: Boolean,
|
|
|
|
+ ) {
|
|
|
|
+ super.doUpdateVisitedHistory(view, url, isReload)
|
|
|
|
+ url?.let {
|
|
|
|
+ currentUrl = it
|
|
|
|
+ onUrlChange(it)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ override fun shouldOverrideUrlLoading(
|
|
|
|
+ view: WebView?,
|
|
|
|
+ request: WebResourceRequest?,
|
|
|
|
+ ): Boolean {
|
|
|
|
+ request?.let {
|
|
|
|
+ view?.loadUrl(it.url.toString(), headers)
|
|
|
|
+ }
|
|
|
|
+ return super.shouldOverrideUrlLoading(view, request)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
Scaffold(
|
|
Scaffold(
|
|
topBar = {
|
|
topBar = {
|
|
@@ -116,61 +168,38 @@ fun WebViewScreenContent(
|
|
}
|
|
}
|
|
},
|
|
},
|
|
) { contentPadding ->
|
|
) { contentPadding ->
|
|
- val webClient = remember {
|
|
|
|
- object : AccompanistWebViewClient() {
|
|
|
|
- override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
|
|
|
|
- super.onPageStarted(view, url, favicon)
|
|
|
|
- url?.let {
|
|
|
|
- currentUrl = it
|
|
|
|
- onUrlChange(it)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ Column(
|
|
|
|
+ modifier = Modifier.padding(contentPadding),
|
|
|
|
+ ) {
|
|
|
|
+ if (showCloudflareHelp) {
|
|
|
|
+ WarningBanner(
|
|
|
|
+ textRes = R.string.information_cloudflare_help,
|
|
|
|
+ modifier = Modifier.clickable {
|
|
|
|
+ uriHandler.openUri("https://tachiyomi.org/help/guides/troubleshooting/#solving-cloudflare-issues")
|
|
|
|
+ },
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WebView(
|
|
|
|
+ state = state,
|
|
|
|
+ modifier = Modifier.weight(1f),
|
|
|
|
+ navigator = navigator,
|
|
|
|
+ onCreated = { webView ->
|
|
|
|
+ webView.setDefaultSettings()
|
|
|
|
|
|
- override fun doUpdateVisitedHistory(
|
|
|
|
- view: WebView,
|
|
|
|
- url: String?,
|
|
|
|
- isReload: Boolean,
|
|
|
|
- ) {
|
|
|
|
- super.doUpdateVisitedHistory(view, url, isReload)
|
|
|
|
- url?.let {
|
|
|
|
- currentUrl = it
|
|
|
|
- onUrlChange(it)
|
|
|
|
|
|
+ // Debug mode (chrome://inspect/#devices)
|
|
|
|
+ if (BuildConfig.DEBUG &&
|
|
|
|
+ 0 != webView.context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
|
|
|
|
+ ) {
|
|
|
|
+ WebView.setWebContentsDebuggingEnabled(true)
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- override fun shouldOverrideUrlLoading(
|
|
|
|
- view: WebView?,
|
|
|
|
- request: WebResourceRequest?,
|
|
|
|
- ): Boolean {
|
|
|
|
- request?.let {
|
|
|
|
- view?.loadUrl(it.url.toString(), headers)
|
|
|
|
|
|
+ headers["user-agent"]?.let {
|
|
|
|
+ webView.settings.userAgentString = it
|
|
}
|
|
}
|
|
- return super.shouldOverrideUrlLoading(view, request)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ },
|
|
|
|
+ client = webClient,
|
|
|
|
+ )
|
|
}
|
|
}
|
|
-
|
|
|
|
- WebView(
|
|
|
|
- state = state,
|
|
|
|
- modifier = Modifier
|
|
|
|
- .padding(contentPadding)
|
|
|
|
- .fillMaxSize(),
|
|
|
|
- navigator = navigator,
|
|
|
|
- onCreated = { webView ->
|
|
|
|
- webView.setDefaultSettings()
|
|
|
|
-
|
|
|
|
- // Debug mode (chrome://inspect/#devices)
|
|
|
|
- if (BuildConfig.DEBUG &&
|
|
|
|
- 0 != webView.context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE
|
|
|
|
- ) {
|
|
|
|
- WebView.setWebContentsDebuggingEnabled(true)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- headers["user-agent"]?.let {
|
|
|
|
- webView.settings.userAgentString = it
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- client = webClient,
|
|
|
|
- )
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|