mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 16:18:55 +01:00 
			
		
		
		
	Migrate WebViewActivity to Compose
This commit is contained in:
		
							
								
								
									
										103
									
								
								app/src/main/java/eu/kanade/presentation/components/AppBar.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								app/src/main/java/eu/kanade/presentation/components/AppBar.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
package eu.kanade.presentation.components
 | 
			
		||||
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
import androidx.compose.material.icons.Icons
 | 
			
		||||
import androidx.compose.material.icons.filled.MoreVert
 | 
			
		||||
import androidx.compose.material3.DropdownMenu
 | 
			
		||||
import androidx.compose.material3.DropdownMenuItem
 | 
			
		||||
import androidx.compose.material3.Icon
 | 
			
		||||
import androidx.compose.material3.IconButton
 | 
			
		||||
import androidx.compose.material3.MaterialTheme
 | 
			
		||||
import androidx.compose.material3.Text
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.getValue
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.runtime.setValue
 | 
			
		||||
import androidx.compose.ui.graphics.vector.ImageVector
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import androidx.compose.ui.text.style.TextOverflow
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun AppBarTitle(
 | 
			
		||||
    title: String?,
 | 
			
		||||
    subtitle: String? = null,
 | 
			
		||||
) {
 | 
			
		||||
    val subtitleTextStyle = MaterialTheme.typography.bodyMedium
 | 
			
		||||
 | 
			
		||||
    Column {
 | 
			
		||||
        title?.let {
 | 
			
		||||
            Text(
 | 
			
		||||
                text = it,
 | 
			
		||||
                maxLines = 1,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        subtitle?.let {
 | 
			
		||||
            Text(
 | 
			
		||||
                text = it,
 | 
			
		||||
                style = subtitleTextStyle,
 | 
			
		||||
                maxLines = 1,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun AppBarActions(
 | 
			
		||||
    actions: List<AppBar.AppBarAction>,
 | 
			
		||||
) {
 | 
			
		||||
    var showMenu by remember { mutableStateOf(false) }
 | 
			
		||||
 | 
			
		||||
    actions.filterIsInstance<AppBar.Action>().map {
 | 
			
		||||
        IconButton(
 | 
			
		||||
            onClick = it.onClick,
 | 
			
		||||
            enabled = it.isEnabled,
 | 
			
		||||
        ) {
 | 
			
		||||
            Icon(
 | 
			
		||||
                imageVector = it.icon,
 | 
			
		||||
                contentDescription = it.title,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val overflowActions = actions.filterIsInstance<AppBar.OverflowAction>()
 | 
			
		||||
    if (overflowActions.isNotEmpty()) {
 | 
			
		||||
        IconButton(onClick = { showMenu = !showMenu }) {
 | 
			
		||||
            Icon(Icons.Default.MoreVert, contentDescription = stringResource(R.string.label_more))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        DropdownMenu(
 | 
			
		||||
            expanded = showMenu,
 | 
			
		||||
            onDismissRequest = { showMenu = false }
 | 
			
		||||
        ) {
 | 
			
		||||
            overflowActions.map {
 | 
			
		||||
                DropdownMenuItem(
 | 
			
		||||
                    onClick = {
 | 
			
		||||
                        it.onClick()
 | 
			
		||||
                        showMenu = false
 | 
			
		||||
                    },
 | 
			
		||||
                    text = { Text(it.title) },
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object AppBar {
 | 
			
		||||
    interface AppBarAction
 | 
			
		||||
 | 
			
		||||
    data class Action(
 | 
			
		||||
        val title: String,
 | 
			
		||||
        val icon: ImageVector,
 | 
			
		||||
        val onClick: () -> Unit,
 | 
			
		||||
        val isEnabled: Boolean = true,
 | 
			
		||||
    ) : AppBarAction
 | 
			
		||||
 | 
			
		||||
    data class OverflowAction(
 | 
			
		||||
        val title: String,
 | 
			
		||||
        val onClick: () -> Unit,
 | 
			
		||||
    ) : AppBarAction
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,152 @@
 | 
			
		||||
package eu.kanade.presentation.webview
 | 
			
		||||
 | 
			
		||||
import android.content.pm.ApplicationInfo
 | 
			
		||||
import android.webkit.WebResourceRequest
 | 
			
		||||
import android.webkit.WebView
 | 
			
		||||
import androidx.compose.foundation.layout.Box
 | 
			
		||||
import androidx.compose.foundation.layout.Column
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.material.icons.Icons
 | 
			
		||||
import androidx.compose.material.icons.filled.ArrowBack
 | 
			
		||||
import androidx.compose.material.icons.filled.ArrowForward
 | 
			
		||||
import androidx.compose.material.icons.filled.Close
 | 
			
		||||
import androidx.compose.material3.Icon
 | 
			
		||||
import androidx.compose.material3.IconButton
 | 
			
		||||
import androidx.compose.material3.LinearProgressIndicator
 | 
			
		||||
import androidx.compose.material3.SmallTopAppBar
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.remember
 | 
			
		||||
import androidx.compose.ui.Modifier
 | 
			
		||||
import androidx.compose.ui.platform.LocalContext
 | 
			
		||||
import androidx.compose.ui.res.stringResource
 | 
			
		||||
import com.google.accompanist.web.AccompanistWebViewClient
 | 
			
		||||
import com.google.accompanist.web.LoadingState
 | 
			
		||||
import com.google.accompanist.web.WebView
 | 
			
		||||
import com.google.accompanist.web.rememberWebViewNavigator
 | 
			
		||||
import com.google.accompanist.web.rememberWebViewState
 | 
			
		||||
import eu.kanade.presentation.components.AppBar
 | 
			
		||||
import eu.kanade.presentation.components.AppBarActions
 | 
			
		||||
import eu.kanade.presentation.components.AppBarTitle
 | 
			
		||||
import eu.kanade.tachiyomi.BuildConfig
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.setDefaultSettings
 | 
			
		||||
 | 
			
		||||
@Composable
 | 
			
		||||
fun WebViewScreen(
 | 
			
		||||
    onUp: () -> Unit,
 | 
			
		||||
    initialTitle: String?,
 | 
			
		||||
    url: String,
 | 
			
		||||
    headers: Map<String, String> = emptyMap(),
 | 
			
		||||
    onShare: (String) -> Unit,
 | 
			
		||||
    onOpenInBrowser: (String) -> Unit,
 | 
			
		||||
    onClearCookies: (String) -> Unit,
 | 
			
		||||
) {
 | 
			
		||||
    val context = LocalContext.current
 | 
			
		||||
    val state = rememberWebViewState(url = url)
 | 
			
		||||
    val navigator = rememberWebViewNavigator()
 | 
			
		||||
 | 
			
		||||
    Column {
 | 
			
		||||
        SmallTopAppBar(
 | 
			
		||||
            title = {
 | 
			
		||||
                AppBarTitle(
 | 
			
		||||
                    title = state.pageTitle ?: initialTitle,
 | 
			
		||||
                    subtitle = state.content.getCurrentUrl(),
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
            navigationIcon = {
 | 
			
		||||
                IconButton(onClick = onUp) {
 | 
			
		||||
                    Icon(
 | 
			
		||||
                        imageVector = Icons.Default.Close,
 | 
			
		||||
                        contentDescription = stringResource(R.string.action_close),
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            actions = {
 | 
			
		||||
                AppBarActions(
 | 
			
		||||
                    listOf(
 | 
			
		||||
                        AppBar.Action(
 | 
			
		||||
                            title = stringResource(R.string.action_webview_back),
 | 
			
		||||
                            icon = Icons.Default.ArrowBack,
 | 
			
		||||
                            onClick = {
 | 
			
		||||
                                if (navigator.canGoBack) {
 | 
			
		||||
                                    navigator.navigateBack()
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            isEnabled = navigator.canGoBack,
 | 
			
		||||
                        ),
 | 
			
		||||
                        AppBar.Action(
 | 
			
		||||
                            title = stringResource(R.string.action_webview_forward),
 | 
			
		||||
                            icon = Icons.Default.ArrowForward,
 | 
			
		||||
                            onClick = {
 | 
			
		||||
                                if (navigator.canGoForward) {
 | 
			
		||||
                                    navigator.navigateForward()
 | 
			
		||||
                                }
 | 
			
		||||
                            },
 | 
			
		||||
                            isEnabled = navigator.canGoForward,
 | 
			
		||||
                        ),
 | 
			
		||||
                        AppBar.OverflowAction(
 | 
			
		||||
                            title = stringResource(R.string.action_webview_refresh),
 | 
			
		||||
                            onClick = { navigator.reload() },
 | 
			
		||||
                        ),
 | 
			
		||||
                        AppBar.OverflowAction(
 | 
			
		||||
                            title = stringResource(R.string.action_share),
 | 
			
		||||
                            onClick = { onShare(state.content.getCurrentUrl()!!) },
 | 
			
		||||
                        ),
 | 
			
		||||
                        AppBar.OverflowAction(
 | 
			
		||||
                            title = stringResource(R.string.action_open_in_browser),
 | 
			
		||||
                            onClick = { onOpenInBrowser(state.content.getCurrentUrl()!!) },
 | 
			
		||||
                        ),
 | 
			
		||||
                        AppBar.OverflowAction(
 | 
			
		||||
                            title = stringResource(R.string.pref_clear_cookies),
 | 
			
		||||
                            onClick = { onClearCookies(state.content.getCurrentUrl()!!) },
 | 
			
		||||
                        ),
 | 
			
		||||
                    ),
 | 
			
		||||
                )
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        Box(modifier = Modifier.weight(1f)) {
 | 
			
		||||
            val loadingState = state.loadingState
 | 
			
		||||
            if (loadingState is LoadingState.Loading) {
 | 
			
		||||
                LinearProgressIndicator(
 | 
			
		||||
                    progress = loadingState.progress,
 | 
			
		||||
                    modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val webClient = remember {
 | 
			
		||||
                object : AccompanistWebViewClient() {
 | 
			
		||||
                    override fun shouldOverrideUrlLoading(
 | 
			
		||||
                        view: WebView?,
 | 
			
		||||
                        request: WebResourceRequest?,
 | 
			
		||||
                    ): Boolean {
 | 
			
		||||
                        request?.let {
 | 
			
		||||
                            view?.loadUrl(it.url.toString(), headers)
 | 
			
		||||
                        }
 | 
			
		||||
                        return super.shouldOverrideUrlLoading(view, request)
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            WebView(
 | 
			
		||||
                state = state,
 | 
			
		||||
                modifier = Modifier.fillMaxSize(),
 | 
			
		||||
                navigator = navigator,
 | 
			
		||||
                onCreated = { webView ->
 | 
			
		||||
                    webView.setDefaultSettings()
 | 
			
		||||
 | 
			
		||||
                    // Debug mode (chrome://inspect/#devices)
 | 
			
		||||
                    if (BuildConfig.DEBUG && 0 != context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) {
 | 
			
		||||
                        WebView.setWebContentsDebuggingEnabled(true)
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    headers["User-Agent"]?.let {
 | 
			
		||||
                        webView.settings.userAgentString = it
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                client = webClient,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,50 +2,28 @@ package eu.kanade.tachiyomi.ui.webview
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.pm.ApplicationInfo
 | 
			
		||||
import android.graphics.Bitmap
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.Menu
 | 
			
		||||
import android.view.MenuItem
 | 
			
		||||
import android.webkit.WebChromeClient
 | 
			
		||||
import android.webkit.WebView
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.core.graphics.ColorUtils
 | 
			
		||||
import androidx.core.view.isInvisible
 | 
			
		||||
import androidx.core.view.isVisible
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
import eu.kanade.tachiyomi.BuildConfig
 | 
			
		||||
import androidx.activity.compose.setContent
 | 
			
		||||
import eu.kanade.presentation.theme.TachiyomiTheme
 | 
			
		||||
import eu.kanade.presentation.webview.WebViewScreen
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.databinding.WebviewActivityBinding
 | 
			
		||||
import eu.kanade.tachiyomi.network.NetworkHelper
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.WebViewClientCompat
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.WebViewUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.getResourceColor
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.logcat
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.openInBrowser
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.setDefaultSettings
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import kotlinx.coroutines.flow.launchIn
 | 
			
		||||
import kotlinx.coroutines.flow.onEach
 | 
			
		||||
import okhttp3.HttpUrl.Companion.toHttpUrl
 | 
			
		||||
import reactivecircus.flowbinding.appcompat.navigationClicks
 | 
			
		||||
import reactivecircus.flowbinding.swiperefreshlayout.refreshes
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
class WebViewActivity : BaseActivity() {
 | 
			
		||||
 | 
			
		||||
    private lateinit var binding: WebviewActivityBinding
 | 
			
		||||
 | 
			
		||||
    private val sourceManager: SourceManager by injectLazy()
 | 
			
		||||
    private val network: NetworkHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private var bundle: Bundle? = null
 | 
			
		||||
 | 
			
		||||
    private var isRefreshing: Boolean = false
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        registerSecureActivity(this)
 | 
			
		||||
    }
 | 
			
		||||
@@ -59,152 +37,33 @@ class WebViewActivity : BaseActivity() {
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            binding = WebviewActivityBinding.inflate(layoutInflater)
 | 
			
		||||
            setContentView(binding.root)
 | 
			
		||||
        } catch (e: Throwable) {
 | 
			
		||||
            // Potentially throws errors like "Error inflating class android.webkit.WebView"
 | 
			
		||||
            toast(R.string.information_webview_required, Toast.LENGTH_LONG)
 | 
			
		||||
            finish()
 | 
			
		||||
            return
 | 
			
		||||
        val url = intent.extras!!.getString(URL_KEY) ?: return
 | 
			
		||||
        var headers = mutableMapOf<String, String>()
 | 
			
		||||
        val source = sourceManager.get(intent.extras!!.getLong(SOURCE_KEY)) as? HttpSource
 | 
			
		||||
        if (source != null) {
 | 
			
		||||
            headers = source.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        title = intent.extras?.getString(TITLE_KEY)
 | 
			
		||||
 | 
			
		||||
        setSupportActionBar(binding.toolbar)
 | 
			
		||||
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
 | 
			
		||||
        binding.toolbar.navigationClicks()
 | 
			
		||||
            .onEach { super.onBackPressed() }
 | 
			
		||||
            .launchIn(lifecycleScope)
 | 
			
		||||
 | 
			
		||||
        binding.swipeRefresh.isEnabled = false
 | 
			
		||||
        binding.swipeRefresh.refreshes()
 | 
			
		||||
            .onEach { refreshPage() }
 | 
			
		||||
            .launchIn(lifecycleScope)
 | 
			
		||||
 | 
			
		||||
        if (bundle == null) {
 | 
			
		||||
            binding.webview.setDefaultSettings()
 | 
			
		||||
 | 
			
		||||
            // Debug mode (chrome://inspect/#devices)
 | 
			
		||||
            if (BuildConfig.DEBUG && 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) {
 | 
			
		||||
                WebView.setWebContentsDebuggingEnabled(true)
 | 
			
		||||
        setContent {
 | 
			
		||||
            TachiyomiTheme {
 | 
			
		||||
                WebViewScreen(
 | 
			
		||||
                    onUp = { finish() },
 | 
			
		||||
                    initialTitle = intent.extras?.getString(TITLE_KEY),
 | 
			
		||||
                    url = url,
 | 
			
		||||
                    headers = headers,
 | 
			
		||||
                    onShare = this::shareWebpage,
 | 
			
		||||
                    onOpenInBrowser = this::openInBrowser,
 | 
			
		||||
                    onClearCookies = this::clearCookies,
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            binding.webview.webChromeClient = object : WebChromeClient() {
 | 
			
		||||
                override fun onProgressChanged(view: WebView?, newProgress: Int) {
 | 
			
		||||
                    binding.progressBar.isVisible = true
 | 
			
		||||
                    binding.progressBar.progress = newProgress
 | 
			
		||||
                    if (newProgress == 100) {
 | 
			
		||||
                        binding.progressBar.isInvisible = true
 | 
			
		||||
                    }
 | 
			
		||||
                    super.onProgressChanged(view, newProgress)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            binding.webview.restoreState(bundle!!)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (bundle == null) {
 | 
			
		||||
            val url = intent.extras!!.getString(URL_KEY) ?: return
 | 
			
		||||
 | 
			
		||||
            var headers = mutableMapOf<String, String>()
 | 
			
		||||
            val source = sourceManager.get(intent.extras!!.getLong(SOURCE_KEY)) as? HttpSource
 | 
			
		||||
            if (source != null) {
 | 
			
		||||
                headers = source.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
 | 
			
		||||
                binding.webview.settings.userAgentString = source.headers["User-Agent"]
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            supportActionBar?.subtitle = url
 | 
			
		||||
 | 
			
		||||
            binding.webview.webViewClient = object : WebViewClientCompat() {
 | 
			
		||||
                override fun shouldOverrideUrlCompat(view: WebView, url: String): Boolean {
 | 
			
		||||
                    view.loadUrl(url, headers)
 | 
			
		||||
                    return true
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
 | 
			
		||||
                    super.onPageStarted(view, url, favicon)
 | 
			
		||||
                    invalidateOptionsMenu()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                override fun onPageFinished(view: WebView?, url: String?) {
 | 
			
		||||
                    super.onPageFinished(view, url)
 | 
			
		||||
                    invalidateOptionsMenu()
 | 
			
		||||
                    title = view?.title
 | 
			
		||||
                    supportActionBar?.subtitle = url
 | 
			
		||||
                    binding.swipeRefresh.isEnabled = true
 | 
			
		||||
                    binding.swipeRefresh.isRefreshing = false
 | 
			
		||||
 | 
			
		||||
                    // Reset to top when page refreshes
 | 
			
		||||
                    if (isRefreshing) {
 | 
			
		||||
                        view?.scrollTo(0, 0)
 | 
			
		||||
                        isRefreshing = false
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            binding.webview.loadUrl(url, headers)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Suppress("UNNECESSARY_SAFE_CALL")
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        // Binding sometimes isn't actually instantiated yet somehow
 | 
			
		||||
        binding?.webview?.destroy()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
 | 
			
		||||
        menuInflater.inflate(R.menu.webview, menu)
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onPrepareOptionsMenu(menu: Menu): Boolean {
 | 
			
		||||
        val iconTintColor = getResourceColor(R.attr.colorOnSurface)
 | 
			
		||||
        val translucentIconTintColor = ColorUtils.setAlphaComponent(iconTintColor, 127)
 | 
			
		||||
 | 
			
		||||
        menu.findItem(R.id.action_web_back).apply {
 | 
			
		||||
            isEnabled = binding.webview.canGoBack()
 | 
			
		||||
            icon.setTint(if (binding.webview.canGoBack()) iconTintColor else translucentIconTintColor)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        menu.findItem(R.id.action_web_forward).apply {
 | 
			
		||||
            isEnabled = binding.webview.canGoForward()
 | 
			
		||||
            icon.setTint(if (binding.webview.canGoForward()) iconTintColor else translucentIconTintColor)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return super.onPrepareOptionsMenu(menu)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
 | 
			
		||||
        when (item.itemId) {
 | 
			
		||||
            R.id.action_web_back -> binding.webview.goBack()
 | 
			
		||||
            R.id.action_web_forward -> binding.webview.goForward()
 | 
			
		||||
            R.id.action_web_refresh -> refreshPage()
 | 
			
		||||
            R.id.action_web_share -> shareWebpage()
 | 
			
		||||
            R.id.action_web_browser -> openInBrowser()
 | 
			
		||||
            R.id.action_clear_cookies -> clearCookies()
 | 
			
		||||
        }
 | 
			
		||||
        return super.onOptionsItemSelected(item)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onBackPressed() {
 | 
			
		||||
        if (binding.webview.canGoBack()) binding.webview.goBack()
 | 
			
		||||
        else super.onBackPressed()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun refreshPage() {
 | 
			
		||||
        binding.swipeRefresh.isRefreshing = true
 | 
			
		||||
        binding.webview.reload()
 | 
			
		||||
        isRefreshing = true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun shareWebpage() {
 | 
			
		||||
    private fun shareWebpage(url: String) {
 | 
			
		||||
        try {
 | 
			
		||||
            val intent = Intent(Intent.ACTION_SEND).apply {
 | 
			
		||||
                type = "text/plain"
 | 
			
		||||
                putExtra(Intent.EXTRA_TEXT, binding.webview.url)
 | 
			
		||||
                putExtra(Intent.EXTRA_TEXT, url)
 | 
			
		||||
            }
 | 
			
		||||
            startActivity(Intent.createChooser(intent, getString(R.string.action_share)))
 | 
			
		||||
        } catch (e: Exception) {
 | 
			
		||||
@@ -212,12 +71,11 @@ class WebViewActivity : BaseActivity() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun openInBrowser() {
 | 
			
		||||
        openInBrowser(binding.webview.url!!, forceDefaultBrowser = true)
 | 
			
		||||
    private fun openInBrowser(url: String) {
 | 
			
		||||
        openInBrowser(url, forceDefaultBrowser = true)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun clearCookies() {
 | 
			
		||||
        val url = binding.webview.url!!
 | 
			
		||||
    private fun clearCookies(url: String) {
 | 
			
		||||
        val cleared = network.cookieManager.remove(url.toHttpUrl())
 | 
			
		||||
        logcat { "Cleared $cleared cookies for: $url" }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ import logcat.LogPriority
 | 
			
		||||
object WebViewUtil {
 | 
			
		||||
    const val SPOOF_PACKAGE_NAME = "org.chromium.chrome"
 | 
			
		||||
 | 
			
		||||
    const val MINIMUM_WEBVIEW_VERSION = 95
 | 
			
		||||
    const val MINIMUM_WEBVIEW_VERSION = 98
 | 
			
		||||
 | 
			
		||||
    fun supportsWebView(context: Context): Boolean {
 | 
			
		||||
        try {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user