package eu.kanade.presentation.webview import android.content.pm.ApplicationInfo import android.webkit.CookieManager import android.webkit.WebView import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Close import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.ProgressIndicatorDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import com.google.accompanist.web.AccompanistWebViewClient import com.google.accompanist.web.LoadingState import com.google.accompanist.web.WebContent 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.Button import eu.kanade.presentation.components.Scaffold import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.util.system.setDefaultSettings @Composable fun EhLoginWebViewScreen( onUp: () -> Unit, onPageFinished: (view: WebView, url: String) -> Unit, onClickRecheckLoginStatus: (loadUrl: (String) -> Unit) -> Unit, onClickAlternateLoginPage: (loadUrl: (String) -> Unit) -> Unit, onClickSkipPageRestyling: (loadUrl: (String) -> Unit) -> Unit, onClickCustomIgneousCookie: () -> Unit, ) { val state = rememberWebViewState( url = "https://forums.e-hentai.org/index.php?act=Login", ) val navigator = rememberWebViewNavigator() val loading by produceState(true) { CookieManager.getInstance().removeAllCookies { value = false } } Scaffold( topBar = { Box { AppBar( title = "ExHentai login", navigateUp = onUp, navigationIcon = Icons.Outlined.Close, ) when (val loadingState = state.loadingState) { is LoadingState.Initializing -> LinearProgressIndicator( modifier = Modifier .fillMaxWidth() .align(Alignment.BottomCenter), ) is LoadingState.Loading -> { val animatedProgress by animateFloatAsState( (loadingState as? LoadingState.Loading)?.progress ?: 1f, animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec, ) LinearProgressIndicator( progress = animatedProgress, modifier = Modifier .fillMaxWidth() .align(Alignment.BottomCenter), ) } else -> {} } } }, ) { contentPadding -> if (loading) { return@Scaffold } val webClient = remember { object : AccompanistWebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) onPageFinished(view ?: return, url ?: return) } } } var showAdvancedOptions by remember { mutableStateOf(false) } Box(Modifier.padding(contentPadding)) { Box { WebView( state = state, navigator = navigator, modifier = Modifier.padding(bottom = 48.dp), onCreated = { webView -> webView.setDefaultSettings() // Debug mode (chrome://inspect/#devices) if (BuildConfig.DEBUG && 0 != webView.context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE ) { WebView.setWebContentsDebuggingEnabled(true) } }, client = webClient, ) Row( Modifier .fillMaxWidth() .height(48.dp) .align(Alignment.BottomCenter), horizontalArrangement = Arrangement.SpaceBetween, ) { Button(onClick = onUp, Modifier.weight(0.5F)) { Text(text = stringResource(android.R.string.cancel)) } Button(onClick = { showAdvancedOptions = true }, Modifier.weight(0.5F)) { Text(text = stringResource(R.string.pref_category_advanced)) } } } if (showAdvancedOptions) { Box(Modifier.background(Color(0xb5000000))) { Dialog(onDismissRequest = { showAdvancedOptions = false }) { fun loadUrl(url: String) { state.content = WebContent.Url(url) } Column(Modifier.fillMaxWidth(0.8F)) { Button( onClick = { onClickRecheckLoginStatus(::loadUrl) showAdvancedOptions = false }, modifier = Modifier.fillMaxWidth(), ) { Text(text = stringResource(R.string.recheck_login_status)) } Button( onClick = { onClickAlternateLoginPage(::loadUrl) showAdvancedOptions = false }, modifier = Modifier.fillMaxWidth(), ) { Text(text = stringResource(R.string.alternative_login_page)) } Button( onClick = { onClickSkipPageRestyling(::loadUrl) showAdvancedOptions = false }, modifier = Modifier.fillMaxWidth(), ) { Text(text = stringResource(R.string.skip_page_restyling)) } Button( onClick = { onClickCustomIgneousCookie() showAdvancedOptions = false }, modifier = Modifier.fillMaxWidth(), ) { Text(text = stringResource(R.string.custom_igneous_cookie)) } Button(onClick = { showAdvancedOptions = false }, Modifier.fillMaxWidth()) { Text(text = stringResource(android.R.string.cancel)) } } } } } } } }