Lint fixes, likely nothing broke
This commit is contained in:
parent
efb8555d76
commit
959bad0247
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.ui.setting
|
package eu.kanade.tachiyomi.ui.setting
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
@ -224,108 +223,118 @@ class SettingsEhController : SettingsController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
preferenceCategory {
|
||||||
preferenceCategory {
|
title = "Gallery update checker"
|
||||||
title = "Gallery update checker"
|
|
||||||
|
|
||||||
intListPreference {
|
intListPreference {
|
||||||
key = PreferenceKeys.eh_autoUpdateFrequency
|
key = PreferenceKeys.eh_autoUpdateFrequency
|
||||||
title = "Time between update batches"
|
title = "Time between update batches"
|
||||||
entries = arrayOf("Never update galleries", "1 hour", "2 hours", "3 hours", "6 hours", "12 hours", "24 hours", "48 hours")
|
entries = arrayOf(
|
||||||
entryValues = arrayOf("0", "1", "2", "3", "6", "12", "24", "48")
|
"Never update galleries",
|
||||||
defaultValue = "0"
|
"1 hour",
|
||||||
|
"2 hours",
|
||||||
|
"3 hours",
|
||||||
|
"6 hours",
|
||||||
|
"12 hours",
|
||||||
|
"24 hours",
|
||||||
|
"48 hours"
|
||||||
|
)
|
||||||
|
entryValues = arrayOf("0", "1", "2", "3", "6", "12", "24", "48")
|
||||||
|
defaultValue = "0"
|
||||||
|
|
||||||
preferences.eh_autoUpdateFrequency().asObservable().subscribeUntilDestroy { newVal ->
|
preferences.eh_autoUpdateFrequency().asObservable()
|
||||||
|
.subscribeUntilDestroy { newVal ->
|
||||||
summary = if (newVal == 0) {
|
summary = if (newVal == 0) {
|
||||||
"${context.getString(R.string.app_name)} will currently never check galleries in your library for updates."
|
"${context.getString(R.string.app_name)} will currently never check galleries in your library for updates."
|
||||||
} else {
|
} else {
|
||||||
"${context.getString(R.string.app_name)} checks/updates galleries in batches. " +
|
"${context.getString(R.string.app_name)} checks/updates galleries in batches. " +
|
||||||
"This means it will wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} galleries," +
|
"This means it will wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} galleries," +
|
||||||
" wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} and so on..."
|
" wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} and so on..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange { newValue ->
|
onChange { newValue ->
|
||||||
val interval = (newValue as String).toInt()
|
val interval = (newValue as String).toInt()
|
||||||
EHentaiUpdateWorker.scheduleBackground(context, interval)
|
EHentaiUpdateWorker.scheduleBackground(context, interval)
|
||||||
true
|
true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
multiSelectListPreference {
|
multiSelectListPreference {
|
||||||
key = PreferenceKeys.eh_autoUpdateRestrictions
|
key = PreferenceKeys.eh_autoUpdateRestrictions
|
||||||
title = "Auto update restrictions"
|
title = "Auto update restrictions"
|
||||||
entriesRes = arrayOf(R.string.wifi, R.string.charging)
|
entriesRes = arrayOf(R.string.wifi, R.string.charging)
|
||||||
entryValues = arrayOf("wifi", "ac")
|
entryValues = arrayOf("wifi", "ac")
|
||||||
summaryRes = R.string.pref_library_update_restriction_summary
|
summaryRes = R.string.pref_library_update_restriction_summary
|
||||||
|
|
||||||
preferences.eh_autoUpdateFrequency().asObservable()
|
preferences.eh_autoUpdateFrequency().asObservable()
|
||||||
.subscribeUntilDestroy { isVisible = it > 0 }
|
.subscribeUntilDestroy { isVisible = it > 0 }
|
||||||
|
|
||||||
onChange {
|
onChange {
|
||||||
// Post to event looper to allow the preference to be updated.
|
// Post to event looper to allow the preference to be updated.
|
||||||
Handler().post { EHentaiUpdateWorker.scheduleBackground(context) }
|
Handler().post { EHentaiUpdateWorker.scheduleBackground(context) }
|
||||||
true
|
true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
preference {
|
preference {
|
||||||
title = "Show updater statistics"
|
title = "Show updater statistics"
|
||||||
|
|
||||||
onClick {
|
onClick {
|
||||||
val progress = MaterialDialog.Builder(context)
|
val progress = MaterialDialog.Builder(context)
|
||||||
.progress(true, 0)
|
.progress(true, 0)
|
||||||
.content("Collecting statistics...")
|
.content("Collecting statistics...")
|
||||||
.cancelable(false)
|
.cancelable(false)
|
||||||
.show()
|
.show()
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
val updateInfo = try {
|
val updateInfo = try {
|
||||||
val stats = preferences.eh_autoUpdateStats().getOrDefault().nullIfBlank()?.let {
|
val stats =
|
||||||
|
preferences.eh_autoUpdateStats().getOrDefault().nullIfBlank()?.let {
|
||||||
gson.fromJson<EHentaiUpdaterStats>(it)
|
gson.fromJson<EHentaiUpdaterStats>(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val statsText = if (stats != null) {
|
val statsText = if (stats != null) {
|
||||||
"The updater last ran ${Humanize.naturalTime(Date(stats.startTime))}, and checked ${stats.updateCount} out of the ${stats.possibleUpdates} galleries that were ready for checking."
|
"The updater last ran ${Humanize.naturalTime(Date(stats.startTime))}, and checked ${stats.updateCount} out of the ${stats.possibleUpdates} galleries that were ready for checking."
|
||||||
} else "The updater has not ran yet."
|
} else "The updater has not ran yet."
|
||||||
|
|
||||||
val allMeta = db.getFavoriteMangaWithMetadata().await().filter {
|
val allMeta = db.getFavoriteMangaWithMetadata().await().filter {
|
||||||
it.source == EH_SOURCE_ID || it.source == EXH_SOURCE_ID
|
it.source == EH_SOURCE_ID || it.source == EXH_SOURCE_ID
|
||||||
}.mapNotNull {
|
}.mapNotNull {
|
||||||
db.getFlatMetadataForManga(it.id!!).await()?.raise<EHentaiSearchMetadata>()
|
db.getFlatMetadataForManga(it.id!!).await()
|
||||||
}.toList()
|
?.raise<EHentaiSearchMetadata>()
|
||||||
|
}.toList()
|
||||||
|
|
||||||
fun metaInRelativeDuration(duration: Interval<*>): Int {
|
fun metaInRelativeDuration(duration: Interval<*>): Int {
|
||||||
val durationMs = duration.inMilliseconds.longValue
|
val durationMs = duration.inMilliseconds.longValue
|
||||||
return allMeta.asSequence().filter {
|
return allMeta.asSequence().filter {
|
||||||
System.currentTimeMillis() - it.lastUpdateCheck < durationMs
|
System.currentTimeMillis() - it.lastUpdateCheck < durationMs
|
||||||
}.count()
|
}.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
$statsText
|
$statsText
|
||||||
|
|
||||||
Galleries that were checked in the last:
|
Galleries that were checked in the last:
|
||||||
- hour: ${metaInRelativeDuration(1.hours)}
|
- hour: ${metaInRelativeDuration(1.hours)}
|
||||||
- 6 hours: ${metaInRelativeDuration(6.hours)}
|
- 6 hours: ${metaInRelativeDuration(6.hours)}
|
||||||
- 12 hours: ${metaInRelativeDuration(12.hours)}
|
- 12 hours: ${metaInRelativeDuration(12.hours)}
|
||||||
- day: ${metaInRelativeDuration(1.days)}
|
- day: ${metaInRelativeDuration(1.days)}
|
||||||
- 2 days: ${metaInRelativeDuration(2.days)}
|
- 2 days: ${metaInRelativeDuration(2.days)}
|
||||||
- week: ${metaInRelativeDuration(7.days)}
|
- week: ${metaInRelativeDuration(7.days)}
|
||||||
- month: ${metaInRelativeDuration(30.days)}
|
- month: ${metaInRelativeDuration(30.days)}
|
||||||
- year: ${metaInRelativeDuration(365.days)}
|
- year: ${metaInRelativeDuration(365.days)}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
} finally {
|
} finally {
|
||||||
progress.dismiss()
|
progress.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
MaterialDialog.Builder(context)
|
MaterialDialog.Builder(context)
|
||||||
.title("Gallery updater statistics")
|
.title("Gallery updater statistics")
|
||||||
.content(updateInfo)
|
.content(updateInfo)
|
||||||
.positiveText("Ok")
|
.positiveText("Ok")
|
||||||
.show()
|
.show()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,9 +97,8 @@ object EXHMigrations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cancel old scheduler jobs with old ids
|
// Cancel old scheduler jobs with old ids
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
context.jobScheduler.cancelAll()
|
||||||
context.jobScheduler.cancelAll()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (oldVersion < 8408) {
|
if (oldVersion < 8408) {
|
||||||
db.inTransaction {
|
db.inTransaction {
|
||||||
|
@ -90,41 +90,25 @@ object DebugFunctions {
|
|||||||
fun convertAllExhentaiGalleriesToEhentai() = convertSources(EXH_SOURCE_ID, EH_SOURCE_ID)
|
fun convertAllExhentaiGalleriesToEhentai() = convertSources(EXH_SOURCE_ID, EH_SOURCE_ID)
|
||||||
|
|
||||||
fun testLaunchEhentaiBackgroundUpdater() {
|
fun testLaunchEhentaiBackgroundUpdater() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
EHentaiUpdateWorker.launchBackgroundTest(app)
|
||||||
EHentaiUpdateWorker.launchBackgroundTest(app)
|
|
||||||
} else {
|
|
||||||
error("OS/SDK version too old!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rescheduleEhentaiBackgroundUpdater() {
|
fun rescheduleEhentaiBackgroundUpdater() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
EHentaiUpdateWorker.scheduleBackground(app)
|
||||||
EHentaiUpdateWorker.scheduleBackground(app)
|
|
||||||
} else {
|
|
||||||
error("OS/SDK version too old!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun listScheduledJobs() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
fun listScheduledJobs() = app.jobScheduler.allPendingJobs.map { j ->
|
||||||
app.jobScheduler.allPendingJobs.map { j ->
|
"""
|
||||||
"""
|
{
|
||||||
{
|
info: ${j.id},
|
||||||
info: ${j.id},
|
isPeriod: ${j.isPeriodic},
|
||||||
isPeriod: ${j.isPeriodic},
|
isPersisted: ${j.isPersisted},
|
||||||
isPersisted: ${j.isPersisted},
|
intervalMillis: ${j.intervalMillis},
|
||||||
intervalMillis: ${j.intervalMillis},
|
}
|
||||||
}
|
""".trimIndent()
|
||||||
""".trimIndent()
|
}.joinToString(",\n")
|
||||||
}.joinToString(",\n")
|
|
||||||
} else {
|
|
||||||
error("OS/SDK version too old!")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun cancelAllScheduledJobs() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
fun cancelAllScheduledJobs() = app.jobScheduler.cancelAll()
|
||||||
app.jobScheduler.cancelAll()
|
|
||||||
} else {
|
|
||||||
error("OS/SDK version too old!")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertSources(from: Long, to: Long) {
|
private fun convertSources(from: Long, to: Long) {
|
||||||
db.lowLevel().executeSQL(RawQuery.builder()
|
db.lowLevel().executeSQL(RawQuery.builder()
|
||||||
|
@ -46,7 +46,6 @@ import uy.kohesive.injekt.Injekt
|
|||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
get() = Dispatchers.Default + Job()
|
get() = Dispatchers.Default + Job()
|
||||||
@ -274,7 +273,6 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val MAX_UPDATE_FAILURES = 5
|
private const val MAX_UPDATE_FAILURES = 5
|
||||||
|
|
||||||
|
@ -118,9 +118,8 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do not update galleries while syncing favorites
|
// Do not update galleries while syncing favorites
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
EHentaiUpdateWorker.cancelBackground(context)
|
||||||
EHentaiUpdateWorker.cancelBackground(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
storage.getRealm().use { realm ->
|
storage.getRealm().use { realm ->
|
||||||
realm.trans {
|
realm.trans {
|
||||||
@ -173,9 +172,8 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update galleries again!
|
// Update galleries again!
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
EHentaiUpdateWorker.scheduleBackground(context)
|
||||||
EHentaiUpdateWorker.scheduleBackground(context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorList.isEmpty())
|
if (errorList.isEmpty())
|
||||||
|
@ -11,7 +11,6 @@ import java.nio.charset.Charset
|
|||||||
import org.jsoup.nodes.DataNode
|
import org.jsoup.nodes.DataNode
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
class AutoSolvingWebViewClient(
|
class AutoSolvingWebViewClient(
|
||||||
activity: BrowserActionActivity,
|
activity: BrowserActionActivity,
|
||||||
verifyComplete: (String) -> Boolean,
|
verifyComplete: (String) -> Boolean,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package exh.ui.captcha
|
package exh.ui.captcha
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import android.webkit.WebViewClient
|
import android.webkit.WebViewClient
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ open class BasicWebViewClient(
|
|||||||
if (verifyComplete(url)) {
|
if (verifyComplete(url)) {
|
||||||
activity.finish()
|
activity.finish()
|
||||||
} else {
|
} else {
|
||||||
if (injectScript != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
if (injectScript != null)
|
||||||
view.evaluateJavascript("(function() {$injectScript})();", null)
|
view.evaluateJavascript("(function() {$injectScript})();", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,14 @@ package exh.ui.captcha
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.webkit.CookieManager
|
import android.webkit.CookieManager
|
||||||
import android.webkit.CookieSyncManager
|
|
||||||
import android.webkit.JavascriptInterface
|
import android.webkit.JavascriptInterface
|
||||||
import android.webkit.JsResult
|
import android.webkit.JsResult
|
||||||
import android.webkit.WebChromeClient
|
import android.webkit.WebChromeClient
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.github.salomonbrys.kotson.get
|
import com.github.salomonbrys.kotson.get
|
||||||
@ -82,7 +79,7 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
val url: String? = intent.getStringExtra(URL_EXTRA)
|
val url: String? = intent.getStringExtra(URL_EXTRA)
|
||||||
val actionName = intent.getStringExtra(ACTION_NAME_EXTRA)
|
val actionName = intent.getStringExtra(ACTION_NAME_EXTRA)
|
||||||
|
|
||||||
val verifyComplete = if (source != null) {
|
@Suppress("NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE") val verifyComplete = if (source != null) {
|
||||||
source::verifyComplete!!
|
source::verifyComplete!!
|
||||||
} else intent.getSerializableExtra(VERIFY_LAMBDA_EXTRA) as? (String) -> Boolean
|
} else intent.getSerializableExtra(VERIFY_LAMBDA_EXTRA) as? (String) -> Boolean
|
||||||
|
|
||||||
@ -106,9 +103,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
cm.setCookie(url, cookieString)
|
cm.setCookie(url, cookieString)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
CookieSyncManager.createInstance(this).sync()
|
|
||||||
|
|
||||||
webview.settings.javaScriptEnabled = true
|
webview.settings.javaScriptEnabled = true
|
||||||
webview.settings.domStorageEnabled = true
|
webview.settings.domStorageEnabled = true
|
||||||
headers.entries.find { it.key.equals("user-agent", true) }?.let {
|
headers.entries.find { it.key.equals("user-agent", true) }?.let {
|
||||||
@ -124,8 +118,7 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
// Wait for both inner scripts to be loaded
|
// Wait for both inner scripts to be loaded
|
||||||
if (loadedInners >= 2) {
|
if (loadedInners >= 2) {
|
||||||
// Attempt to autosolve captcha
|
// Attempt to autosolve captcha
|
||||||
if (preferencesHelper.eh_autoSolveCaptchas().getOrDefault() &&
|
if (preferencesHelper.eh_autoSolveCaptchas().getOrDefault()) {
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
webview.post {
|
webview.post {
|
||||||
// 10 seconds to auto-solve captcha
|
// 10 seconds to auto-solve captcha
|
||||||
strictValidationStartTime = System.currentTimeMillis() + 1000 * 10
|
strictValidationStartTime = System.currentTimeMillis() + 1000 * 10
|
||||||
@ -144,28 +137,24 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webview.webViewClient = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
webview.webViewClient = if (actionName == null && preferencesHelper.eh_autoSolveCaptchas().getOrDefault()) {
|
||||||
if (actionName == null && preferencesHelper.eh_autoSolveCaptchas().getOrDefault()) {
|
// Fetch auto-solve credentials early for speed
|
||||||
// Fetch auto-solve credentials early for speed
|
credentialsObservable = httpClient.newCall(Request.Builder()
|
||||||
credentialsObservable = httpClient.newCall(Request.Builder()
|
// Rob demo credentials
|
||||||
// Rob demo credentials
|
.url("https://speech-to-text-demo.ng.bluemix.net/api/v1/credentials")
|
||||||
.url("https://speech-to-text-demo.ng.bluemix.net/api/v1/credentials")
|
.build())
|
||||||
.build())
|
.asObservableSuccess()
|
||||||
.asObservableSuccess()
|
.subscribeOn(Schedulers.io())
|
||||||
.subscribeOn(Schedulers.io())
|
.map {
|
||||||
.map {
|
val json = JsonParser.parseString(it.body!!.string())
|
||||||
val json = JsonParser.parseString(it.body!!.string())
|
it.close()
|
||||||
it.close()
|
json["token"].string
|
||||||
json["token"].string
|
}.melt()
|
||||||
}.melt()
|
|
||||||
|
|
||||||
webview.addJavascriptInterface(this@BrowserActionActivity, "exh")
|
webview.addJavascriptInterface(this@BrowserActionActivity, "exh")
|
||||||
AutoSolvingWebViewClient(this, verifyComplete, script, headers)
|
AutoSolvingWebViewClient(this, verifyComplete, script, headers)
|
||||||
} else {
|
|
||||||
HeadersInjectingWebViewClient(this, verifyComplete, script, headers)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
BasicWebViewClient(this, verifyComplete, script)
|
HeadersInjectingWebViewClient(this, verifyComplete, script, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
webview.loadUrl(url, headers)
|
webview.loadUrl(url, headers)
|
||||||
@ -180,7 +169,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.KITKAT)
|
|
||||||
fun captchaSolveFail() {
|
fun captchaSolveFail() {
|
||||||
currentLoopId = null
|
currentLoopId = null
|
||||||
validateCurrentLoopId = null
|
validateCurrentLoopId = null
|
||||||
@ -197,7 +185,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
fun callback(result: String?, loopId: String, stage: Int) {
|
fun callback(result: String?, loopId: String, stage: Int) {
|
||||||
if (loopId != currentLoopId) return
|
if (loopId != currentLoopId) return
|
||||||
@ -295,7 +282,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
}.toSingle()
|
}.toSingle()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun doStageCheckbox(loopId: String) {
|
fun doStageCheckbox(loopId: String) {
|
||||||
if (loopId != currentLoopId) return
|
if (loopId != currentLoopId) return
|
||||||
|
|
||||||
@ -324,7 +310,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
""".trimIndent().replace("\n", ""), null)
|
""".trimIndent().replace("\n", ""), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun getAudioButtonLocation(loopId: String) {
|
fun getAudioButtonLocation(loopId: String) {
|
||||||
webview.evaluateJavascript("""
|
webview.evaluateJavascript("""
|
||||||
(function() {
|
(function() {
|
||||||
@ -357,7 +342,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
""".trimIndent().replace("\n", ""), null)
|
""".trimIndent().replace("\n", ""), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun doStageDownloadAudio(loopId: String) {
|
fun doStageDownloadAudio(loopId: String) {
|
||||||
webview.evaluateJavascript("""
|
webview.evaluateJavascript("""
|
||||||
(function() {
|
(function() {
|
||||||
@ -383,7 +367,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
""".trimIndent().replace("\n", ""), null)
|
""".trimIndent().replace("\n", ""), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun typeResult(loopId: String, result: String) {
|
fun typeResult(loopId: String, result: String) {
|
||||||
webview.evaluateJavascript("""
|
webview.evaluateJavascript("""
|
||||||
(function() {
|
(function() {
|
||||||
@ -412,14 +395,12 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
""".trimIndent().replace("\n", ""), null)
|
""".trimIndent().replace("\n", ""), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun beginSolveLoop() {
|
fun beginSolveLoop() {
|
||||||
val loopId = UUID.randomUUID().toString()
|
val loopId = UUID.randomUUID().toString()
|
||||||
currentLoopId = loopId
|
currentLoopId = loopId
|
||||||
doStageCheckbox(loopId)
|
doStageCheckbox(loopId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
fun validateCaptchaCallback(result: Boolean, loopId: String) {
|
fun validateCaptchaCallback(result: Boolean, loopId: String) {
|
||||||
if (loopId != validateCurrentLoopId) return
|
if (loopId != validateCurrentLoopId) return
|
||||||
@ -448,7 +429,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun runValidateCaptcha(loopId: String) {
|
fun runValidateCaptcha(loopId: String) {
|
||||||
if (loopId != validateCurrentLoopId) return
|
if (loopId != validateCurrentLoopId) return
|
||||||
|
|
||||||
@ -476,7 +456,6 @@ class BrowserActionActivity : AppCompatActivity() {
|
|||||||
""".trimIndent().replace("\n", ""), null)
|
""".trimIndent().replace("\n", ""), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun beginValidateCaptchaLoop() {
|
fun beginValidateCaptchaLoop() {
|
||||||
val loopId = UUID.randomUUID().toString()
|
val loopId = UUID.randomUUID().toString()
|
||||||
validateCurrentLoopId = loopId
|
validateCurrentLoopId = loopId
|
||||||
|
@ -6,7 +6,6 @@ import android.webkit.WebResourceResponse
|
|||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
open class HeadersInjectingWebViewClient(
|
open class HeadersInjectingWebViewClient(
|
||||||
activity: BrowserActionActivity,
|
activity: BrowserActionActivity,
|
||||||
verifyComplete: (String) -> Boolean,
|
verifyComplete: (String) -> Boolean,
|
||||||
|
@ -5,7 +5,6 @@ import android.webkit.WebResourceRequest
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun WebResourceRequest.toOkHttpRequest(): Request {
|
fun WebResourceRequest.toOkHttpRequest(): Request {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(url.toString())
|
.url(url.toString())
|
||||||
|
@ -6,17 +6,13 @@ import com.bluelinelabs.conductor.Router
|
|||||||
import com.bluelinelabs.conductor.RouterTransaction
|
import com.bluelinelabs.conductor.RouterTransaction
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import eu.kanade.tachiyomi.util.lang.launchInUI
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
object LockActivityDelegate {
|
object LockActivityDelegate {
|
||||||
private val preferences by injectLazy<PreferencesHelper>()
|
private val preferences by injectLazy<PreferencesHelper>()
|
||||||
|
|
||||||
val uiScope = CoroutineScope(Dispatchers.Main)
|
|
||||||
|
|
||||||
var willLock: Boolean = true
|
var willLock: Boolean = true
|
||||||
|
|
||||||
fun doLock(router: Router, animate: Boolean = false) {
|
fun doLock(router: Router, animate: Boolean = false) {
|
||||||
@ -33,7 +29,7 @@ object LockActivityDelegate {
|
|||||||
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launchIn(uiScope)
|
.launchInUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onResume(activity: FragmentActivity, router: Router) {
|
fun onResume(activity: FragmentActivity, router: Router) {
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package exh.ui.lock
|
package exh.ui.lock
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.app.AppOpsManager
|
import android.app.AppOpsManager
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.elvishew.xlog.XLog
|
import com.elvishew.xlog.XLog
|
||||||
@ -55,7 +53,6 @@ fun notifyLockSecurity(
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
return false
|
return false
|
||||||
if (!prefs.eh_lockManually().getOrDefault() &&
|
if (!prefs.eh_lockManually().getOrDefault() &&
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
|
|
||||||
!hasAccessToUsageStats(context)) {
|
!hasAccessToUsageStats(context)) {
|
||||||
MaterialDialog.Builder(context)
|
MaterialDialog.Builder(context)
|
||||||
.title("Permission required")
|
.title("Permission required")
|
||||||
@ -89,7 +86,6 @@ fun notifyLockSecurity(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
||||||
fun hasAccessToUsageStats(context: Context): Boolean {
|
fun hasAccessToUsageStats(context: Context): Boolean {
|
||||||
return try {
|
return try {
|
||||||
val packageManager = context.packageManager
|
val packageManager = context.packageManager
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package exh.ui.login
|
package exh.ui.login
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -70,55 +69,46 @@ class LoginController : NucleusController<EhActivityLoginBinding, LoginPresenter
|
|||||||
binding.webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login&$PARAM_SKIP_INJECT=true")
|
binding.webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login&$PARAM_SKIP_INJECT=true")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
CookieManager.getInstance().removeAllCookies {
|
||||||
CookieManager.getInstance().removeAllCookies {
|
launchUI {
|
||||||
launchUI {
|
startWebview(view)
|
||||||
startWebview(view)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
CookieManager.getInstance().removeAllCookie()
|
|
||||||
startWebview(view)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideAdvancedOptions(view: View) {
|
private fun hideAdvancedOptions(view: View) {
|
||||||
with(view) {
|
binding.advancedOptions.gone()
|
||||||
binding.advancedOptions.gone()
|
binding.webview.visible()
|
||||||
binding.webview.visible()
|
binding.btnAdvanced.isEnabled = true
|
||||||
binding.btnAdvanced.isEnabled = true
|
binding.btnCancel.isEnabled = true
|
||||||
binding.btnCancel.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startWebview(view: View) {
|
fun startWebview(view: View) {
|
||||||
with(view) {
|
binding.webview.settings.javaScriptEnabled = true
|
||||||
binding.webview.settings.javaScriptEnabled = true
|
binding.webview.settings.domStorageEnabled = true
|
||||||
binding.webview.settings.domStorageEnabled = true
|
|
||||||
|
|
||||||
binding.webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login")
|
binding.webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login")
|
||||||
|
|
||||||
binding.webview.webViewClient = object : WebViewClient() {
|
binding.webview.webViewClient = object : WebViewClient() {
|
||||||
override fun onPageFinished(view: WebView, url: String) {
|
override fun onPageFinished(view: WebView, url: String) {
|
||||||
super.onPageFinished(view, url)
|
super.onPageFinished(view, url)
|
||||||
Timber.d(url)
|
Timber.d(url)
|
||||||
val parsedUrl = Uri.parse(url)
|
val parsedUrl = Uri.parse(url)
|
||||||
if (parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
|
if (parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
|
||||||
// Hide distracting content
|
// Hide distracting content
|
||||||
if (!parsedUrl.queryParameterNames.contains(PARAM_SKIP_INJECT))
|
if (!parsedUrl.queryParameterNames.contains(PARAM_SKIP_INJECT))
|
||||||
view.evaluateJavascript(HIDE_JS, null)
|
view.evaluateJavascript(HIDE_JS, null)
|
||||||
|
|
||||||
// Check login result
|
// Check login result
|
||||||
if (parsedUrl.getQueryParameter("code")?.toInt() != 0) {
|
if (parsedUrl.getQueryParameter("code")?.toInt() != 0) {
|
||||||
if (checkLoginCookies(url)) view.loadUrl("https://exhentai.org/")
|
if (checkLoginCookies(url)) view.loadUrl("https://exhentai.org/")
|
||||||
}
|
}
|
||||||
} else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
|
} else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
|
||||||
// At ExHentai, check that everything worked out...
|
// At ExHentai, check that everything worked out...
|
||||||
if (applyExHentaiCookies(url)) {
|
if (applyExHentaiCookies(url)) {
|
||||||
preferenceManager.enableExhentai().set(true)
|
preferenceManager.enableExhentai().set(true)
|
||||||
finishLogin()
|
finishLogin()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class CachedField<T>(private val expiresAfterMs: Long) {
|
|||||||
content = producer()
|
content = producer()
|
||||||
}
|
}
|
||||||
|
|
||||||
content as T
|
content!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,12 @@ class DeferredField<T> {
|
|||||||
*/
|
*/
|
||||||
suspend fun get(): T {
|
suspend fun get(): T {
|
||||||
// Check if field is initialized and return immediately if it is
|
// Check if field is initialized and return immediately if it is
|
||||||
if (initialized) return content as T
|
if (initialized) return content!!
|
||||||
|
|
||||||
// Wait for field to initialize
|
// Wait for field to initialize
|
||||||
mutex.withLock {}
|
mutex.withLock {}
|
||||||
|
|
||||||
// Field is initialized, return value
|
// Field is initialized, return value
|
||||||
return content as T
|
return content!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ class NakedTrieNode<T>(val key: Int, var parent: NakedTrieNode<T>?) {
|
|||||||
inline fun walk(prefix: String, consumer: (String, T) -> Boolean, leavesOnly: Boolean) {
|
inline fun walk(prefix: String, consumer: (String, T) -> Boolean, leavesOnly: Boolean) {
|
||||||
// Special case root
|
// Special case root
|
||||||
if (hasData && (!leavesOnly || children.size() <= 0)) {
|
if (hasData && (!leavesOnly || children.size() <= 0)) {
|
||||||
if (!consumer(prefix, data as T)) return
|
if (!consumer(prefix, data!! as T)) return
|
||||||
}
|
}
|
||||||
|
|
||||||
val stack = LinkedList<Pair<String, NakedTrieNode<T>>>()
|
val stack = LinkedList<Pair<String, NakedTrieNode<T>>>()
|
||||||
@ -27,7 +27,7 @@ class NakedTrieNode<T>(val key: Int, var parent: NakedTrieNode<T>?) {
|
|||||||
stack += key + it.key.toChar() to it
|
stack += key + it.key.toChar() to it
|
||||||
}
|
}
|
||||||
if (bottom.hasData && (!leavesOnly || bottom.children.size() <= 0)) {
|
if (bottom.hasData && (!leavesOnly || bottom.children.size() <= 0)) {
|
||||||
if (!consumer(key, bottom.data as T)) return
|
if (!consumer(key, bottom.data!! as T)) return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ class NakedTrie<T> : MutableMap<String, T> {
|
|||||||
version++
|
version++
|
||||||
}
|
}
|
||||||
|
|
||||||
return current.data as T
|
return current.data!!
|
||||||
}
|
}
|
||||||
|
|
||||||
// Includes root
|
// Includes root
|
||||||
|
Loading…
x
Reference in New Issue
Block a user