Convert EhLoginActivity to compose

This commit is contained in:
Jobobby04 2022-09-13 18:18:48 -04:00
parent f28342601b
commit 3807fb0607
2 changed files with 237 additions and 146 deletions

View File

@ -0,0 +1,197 @@
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.filled.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.Default.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))
}
}
}
}
}
}
}
}

View File

@ -2,33 +2,21 @@ package exh.ui.login
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.net.Uri
import android.os.Bundle
import android.webkit.CookieManager
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.presentation.webview.EhLoginWebViewScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.EhActivityLoginBinding
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.WebViewUtil
import eu.kanade.tachiyomi.util.system.setDefaultSettings
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.setComposeContent
import eu.kanade.tachiyomi.widget.materialdialogs.setTextInput
import exh.log.xLogD
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.appcompat.navigationClicks
import uy.kohesive.injekt.injectLazy
import java.net.HttpCookie
import java.util.Locale
@ -37,13 +25,7 @@ import java.util.Locale
* LoginController
*/
class EhLoginActivity : BaseActivity() {
lateinit var binding: EhActivityLoginBinding
val preferenceManager: PreferencesHelper by injectLazy()
val sourceManager: SourceManager by injectLazy()
private var bundle: Bundle? = null
private val preferenceManager: PreferencesHelper by injectLazy()
private var igneous: String? = null
@ -56,95 +38,28 @@ class EhLoginActivity : BaseActivity() {
return
}
try {
binding = EhActivityLoginBinding.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
}
title = "ExHentai login"
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
binding.toolbar.navigationClicks()
.onEach { finish() }
.launchIn(lifecycleScope)
onViewCreated()
if (bundle == null) {
binding.webview.setDefaultSettings()
// Debug mode (chrome://inspect/#devices)
if (BuildConfig.DEBUG && 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) {
WebView.setWebContentsDebuggingEnabled(true)
}
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) {
startWebview()
setComposeContent {
EhLoginWebViewScreen(
onUp = { finish() },
onPageFinished = ::onPageFinished,
onClickRecheckLoginStatus = ::recheckLoginStatus,
onClickAlternateLoginPage = ::alternateLoginPage,
onClickSkipPageRestyling = ::skipPageRestyling,
onClickCustomIgneousCookie = ::openIgneousDialog,
)
}
}
fun onViewCreated() {
binding.btnCancel.setOnClickListener { finish() }
binding.btnAdvanced.setOnClickListener {
binding.advancedOptions.isVisible = true
binding.webview.isVisible = false
binding.btnAdvanced.isEnabled = false
binding.btnCancel.isEnabled = false
private fun recheckLoginStatus(loadUrl: (String) -> Unit) {
loadUrl("https://exhentai.org/")
}
binding.btnClose.setOnClickListener {
hideAdvancedOptions()
private fun alternateLoginPage(loadUrl: (String) -> Unit) {
loadUrl("https://e-hentai.org/bounce_login.php")
}
binding.btnRecheck.setOnClickListener {
hideAdvancedOptions()
binding.webview.loadUrl("https://exhentai.org/")
}
binding.btnAltLogin.setOnClickListener {
hideAdvancedOptions()
binding.webview.loadUrl("https://e-hentai.org/bounce_login.php")
}
binding.btnSkipRestyle.setOnClickListener {
hideAdvancedOptions()
binding.webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login&$PARAM_SKIP_INJECT=true")
}
binding.btnIgneousCookie.setOnClickListener {
hideAdvancedOptions()
openIgneousDialog()
}
CookieManager.getInstance().removeAllCookies {
launchUI {
if (bundle == null) {
startWebview()
}
}
}
private fun skipPageRestyling(loadUrl: (String) -> Unit) {
loadUrl("https://forums.e-hentai.org/index.php?act=Login&$PARAM_SKIP_INJECT=true")
}
private fun openIgneousDialog() {
@ -164,21 +79,7 @@ class EhLoginActivity : BaseActivity() {
.show()
}
private fun hideAdvancedOptions() {
binding.advancedOptions.isVisible = false
binding.webview.isVisible = true
binding.btnAdvanced.isEnabled = true
binding.btnCancel.isEnabled = true
}
private fun startWebview() {
binding.webview.setDefaultSettings()
binding.webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login")
binding.webview.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
private fun onPageFinished(view: WebView, url: String) {
xLogD(url)
val parsedUrl = Uri.parse(url)
if (parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
@ -200,18 +101,11 @@ class EhLoginActivity : BaseActivity() {
}
}
}
}
}
override fun onDestroy() {
binding.webview?.destroy()
super.onDestroy()
}
/**
* Check if we are logged in
*/
fun checkLoginCookies(url: String): Boolean {
private fun checkLoginCookies(url: String): Boolean {
getCookies(url)?.let { parsed ->
return parsed.count {
(
@ -227,7 +121,7 @@ class EhLoginActivity : BaseActivity() {
/**
* Parse cookies at ExHentai
*/
fun applyExHentaiCookies(url: String): Boolean {
private fun applyExHentaiCookies(url: String): Boolean {
getCookies(url)?.let { parsed ->
var memberId: String? = null