Lint fixes, likely nothing broke

This commit is contained in:
Jobobby04 2020-04-22 17:26:46 -04:00
parent efb8555d76
commit 959bad0247
16 changed files with 160 additions and 215 deletions

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.setting
import android.os.Build
import android.os.Handler
import android.widget.Toast
import androidx.preference.PreferenceScreen
@ -224,108 +223,118 @@ class SettingsEhController : SettingsController() {
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
preferenceCategory {
title = "Gallery update checker"
preferenceCategory {
title = "Gallery update checker"
intListPreference {
key = PreferenceKeys.eh_autoUpdateFrequency
title = "Time between update batches"
entries = arrayOf("Never update galleries", "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"
intListPreference {
key = PreferenceKeys.eh_autoUpdateFrequency
title = "Time between update batches"
entries = arrayOf(
"Never update galleries",
"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) {
"${context.getString(R.string.app_name)} will currently never check galleries in your library for updates."
} else {
"${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," +
" wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} and so on..."
"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..."
}
}
onChange { newValue ->
val interval = (newValue as String).toInt()
EHentaiUpdateWorker.scheduleBackground(context, interval)
true
}
onChange { newValue ->
val interval = (newValue as String).toInt()
EHentaiUpdateWorker.scheduleBackground(context, interval)
true
}
}
multiSelectListPreference {
key = PreferenceKeys.eh_autoUpdateRestrictions
title = "Auto update restrictions"
entriesRes = arrayOf(R.string.wifi, R.string.charging)
entryValues = arrayOf("wifi", "ac")
summaryRes = R.string.pref_library_update_restriction_summary
multiSelectListPreference {
key = PreferenceKeys.eh_autoUpdateRestrictions
title = "Auto update restrictions"
entriesRes = arrayOf(R.string.wifi, R.string.charging)
entryValues = arrayOf("wifi", "ac")
summaryRes = R.string.pref_library_update_restriction_summary
preferences.eh_autoUpdateFrequency().asObservable()
.subscribeUntilDestroy { isVisible = it > 0 }
preferences.eh_autoUpdateFrequency().asObservable()
.subscribeUntilDestroy { isVisible = it > 0 }
onChange {
// Post to event looper to allow the preference to be updated.
Handler().post { EHentaiUpdateWorker.scheduleBackground(context) }
true
}
onChange {
// Post to event looper to allow the preference to be updated.
Handler().post { EHentaiUpdateWorker.scheduleBackground(context) }
true
}
}
preference {
title = "Show updater statistics"
preference {
title = "Show updater statistics"
onClick {
val progress = MaterialDialog.Builder(context)
.progress(true, 0)
.content("Collecting statistics...")
.cancelable(false)
.show()
onClick {
val progress = MaterialDialog.Builder(context)
.progress(true, 0)
.content("Collecting statistics...")
.cancelable(false)
.show()
GlobalScope.launch(Dispatchers.IO) {
val updateInfo = try {
val stats = preferences.eh_autoUpdateStats().getOrDefault().nullIfBlank()?.let {
GlobalScope.launch(Dispatchers.IO) {
val updateInfo = try {
val stats =
preferences.eh_autoUpdateStats().getOrDefault().nullIfBlank()?.let {
gson.fromJson<EHentaiUpdaterStats>(it)
}
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."
} else "The updater has not ran yet."
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."
} else "The updater has not ran yet."
val allMeta = db.getFavoriteMangaWithMetadata().await().filter {
it.source == EH_SOURCE_ID || it.source == EXH_SOURCE_ID
}.mapNotNull {
db.getFlatMetadataForManga(it.id!!).await()?.raise<EHentaiSearchMetadata>()
}.toList()
val allMeta = db.getFavoriteMangaWithMetadata().await().filter {
it.source == EH_SOURCE_ID || it.source == EXH_SOURCE_ID
}.mapNotNull {
db.getFlatMetadataForManga(it.id!!).await()
?.raise<EHentaiSearchMetadata>()
}.toList()
fun metaInRelativeDuration(duration: Interval<*>): Int {
val durationMs = duration.inMilliseconds.longValue
return allMeta.asSequence().filter {
System.currentTimeMillis() - it.lastUpdateCheck < durationMs
}.count()
}
fun metaInRelativeDuration(duration: Interval<*>): Int {
val durationMs = duration.inMilliseconds.longValue
return allMeta.asSequence().filter {
System.currentTimeMillis() - it.lastUpdateCheck < durationMs
}.count()
}
"""
$statsText
"""
$statsText
Galleries that were checked in the last:
- hour: ${metaInRelativeDuration(1.hours)}
- 6 hours: ${metaInRelativeDuration(6.hours)}
- 12 hours: ${metaInRelativeDuration(12.hours)}
- day: ${metaInRelativeDuration(1.days)}
- 2 days: ${metaInRelativeDuration(2.days)}
- week: ${metaInRelativeDuration(7.days)}
- month: ${metaInRelativeDuration(30.days)}
- year: ${metaInRelativeDuration(365.days)}
Galleries that were checked in the last:
- hour: ${metaInRelativeDuration(1.hours)}
- 6 hours: ${metaInRelativeDuration(6.hours)}
- 12 hours: ${metaInRelativeDuration(12.hours)}
- day: ${metaInRelativeDuration(1.days)}
- 2 days: ${metaInRelativeDuration(2.days)}
- week: ${metaInRelativeDuration(7.days)}
- month: ${metaInRelativeDuration(30.days)}
- year: ${metaInRelativeDuration(365.days)}
""".trimIndent()
} finally {
progress.dismiss()
}
} finally {
progress.dismiss()
}
withContext(Dispatchers.Main) {
MaterialDialog.Builder(context)
.title("Gallery updater statistics")
.content(updateInfo)
.positiveText("Ok")
.show()
}
withContext(Dispatchers.Main) {
MaterialDialog.Builder(context)
.title("Gallery updater statistics")
.content(updateInfo)
.positiveText("Ok")
.show()
}
}
}

@ -97,9 +97,8 @@ object EXHMigrations {
}
// 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) {
db.inTransaction {

@ -90,41 +90,25 @@ object DebugFunctions {
fun convertAllExhentaiGalleriesToEhentai() = convertSources(EXH_SOURCE_ID, EH_SOURCE_ID)
fun testLaunchEhentaiBackgroundUpdater() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
EHentaiUpdateWorker.launchBackgroundTest(app)
} else {
error("OS/SDK version too old!")
}
EHentaiUpdateWorker.launchBackgroundTest(app)
}
fun rescheduleEhentaiBackgroundUpdater() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
EHentaiUpdateWorker.scheduleBackground(app)
} else {
error("OS/SDK version too old!")
}
EHentaiUpdateWorker.scheduleBackground(app)
}
fun listScheduledJobs() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
app.jobScheduler.allPendingJobs.map { j ->
"""
{
info: ${j.id},
isPeriod: ${j.isPeriodic},
isPersisted: ${j.isPersisted},
intervalMillis: ${j.intervalMillis},
}
""".trimIndent()
}.joinToString(",\n")
} else {
error("OS/SDK version too old!")
}
fun listScheduledJobs() = app.jobScheduler.allPendingJobs.map { j ->
"""
{
info: ${j.id},
isPeriod: ${j.isPeriodic},
isPersisted: ${j.isPersisted},
intervalMillis: ${j.intervalMillis},
}
""".trimIndent()
}.joinToString(",\n")
fun cancelAllScheduledJobs() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
app.jobScheduler.cancelAll()
} else {
error("OS/SDK version too old!")
}
fun cancelAllScheduledJobs() = app.jobScheduler.cancelAll()
private fun convertSources(from: Long, to: Long) {
db.lowLevel().executeSQL(RawQuery.builder()

@ -46,7 +46,6 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class EHentaiUpdateWorker : JobService(), CoroutineScope {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Default + Job()
@ -274,7 +273,6 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
}
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
companion object {
private const val MAX_UPDATE_FAILURES = 5

@ -118,9 +118,8 @@ class FavoritesSyncHelper(val context: Context) {
}
// 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 ->
realm.trans {
@ -173,9 +172,8 @@ class FavoritesSyncHelper(val context: Context) {
}
// Update galleries again!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
EHentaiUpdateWorker.scheduleBackground(context)
}
EHentaiUpdateWorker.scheduleBackground(context)
}
if (errorList.isEmpty())

@ -11,7 +11,6 @@ import java.nio.charset.Charset
import org.jsoup.nodes.DataNode
import org.jsoup.nodes.Element
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class AutoSolvingWebViewClient(
activity: BrowserActionActivity,
verifyComplete: (String) -> Boolean,

@ -1,6 +1,5 @@
package exh.ui.captcha
import android.os.Build
import android.webkit.WebView
import android.webkit.WebViewClient
@ -15,7 +14,7 @@ open class BasicWebViewClient(
if (verifyComplete(url)) {
activity.finish()
} else {
if (injectScript != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
if (injectScript != null)
view.evaluateJavascript("(function() {$injectScript})();", null)
}
}

@ -2,17 +2,14 @@ package exh.ui.captcha
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.SystemClock
import android.view.MotionEvent
import android.webkit.CookieManager
import android.webkit.CookieSyncManager
import android.webkit.JavascriptInterface
import android.webkit.JsResult
import android.webkit.WebChromeClient
import android.webkit.WebView
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.github.salomonbrys.kotson.get
@ -82,7 +79,7 @@ class BrowserActionActivity : AppCompatActivity() {
val url: String? = intent.getStringExtra(URL_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!!
} else intent.getSerializableExtra(VERIFY_LAMBDA_EXTRA) as? (String) -> Boolean
@ -106,9 +103,6 @@ class BrowserActionActivity : AppCompatActivity() {
cm.setCookie(url, cookieString)
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
CookieSyncManager.createInstance(this).sync()
webview.settings.javaScriptEnabled = true
webview.settings.domStorageEnabled = true
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
if (loadedInners >= 2) {
// Attempt to autosolve captcha
if (preferencesHelper.eh_autoSolveCaptchas().getOrDefault() &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (preferencesHelper.eh_autoSolveCaptchas().getOrDefault()) {
webview.post {
// 10 seconds to auto-solve captcha
strictValidationStartTime = System.currentTimeMillis() + 1000 * 10
@ -144,28 +137,24 @@ class BrowserActionActivity : AppCompatActivity() {
}
}
webview.webViewClient = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (actionName == null && preferencesHelper.eh_autoSolveCaptchas().getOrDefault()) {
// Fetch auto-solve credentials early for speed
credentialsObservable = httpClient.newCall(Request.Builder()
// Rob demo credentials
.url("https://speech-to-text-demo.ng.bluemix.net/api/v1/credentials")
.build())
.asObservableSuccess()
.subscribeOn(Schedulers.io())
.map {
val json = JsonParser.parseString(it.body!!.string())
it.close()
json["token"].string
}.melt()
webview.webViewClient = if (actionName == null && preferencesHelper.eh_autoSolveCaptchas().getOrDefault()) {
// Fetch auto-solve credentials early for speed
credentialsObservable = httpClient.newCall(Request.Builder()
// Rob demo credentials
.url("https://speech-to-text-demo.ng.bluemix.net/api/v1/credentials")
.build())
.asObservableSuccess()
.subscribeOn(Schedulers.io())
.map {
val json = JsonParser.parseString(it.body!!.string())
it.close()
json["token"].string
}.melt()
webview.addJavascriptInterface(this@BrowserActionActivity, "exh")
AutoSolvingWebViewClient(this, verifyComplete, script, headers)
} else {
HeadersInjectingWebViewClient(this, verifyComplete, script, headers)
}
webview.addJavascriptInterface(this@BrowserActionActivity, "exh")
AutoSolvingWebViewClient(this, verifyComplete, script, headers)
} else {
BasicWebViewClient(this, verifyComplete, script)
HeadersInjectingWebViewClient(this, verifyComplete, script, headers)
}
webview.loadUrl(url, headers)
@ -180,7 +169,6 @@ class BrowserActionActivity : AppCompatActivity() {
return true
}
@RequiresApi(Build.VERSION_CODES.KITKAT)
fun captchaSolveFail() {
currentLoopId = null
validateCurrentLoopId = null
@ -197,7 +185,6 @@ class BrowserActionActivity : AppCompatActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JavascriptInterface
fun callback(result: String?, loopId: String, stage: Int) {
if (loopId != currentLoopId) return
@ -295,7 +282,6 @@ class BrowserActionActivity : AppCompatActivity() {
}.toSingle()
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun doStageCheckbox(loopId: String) {
if (loopId != currentLoopId) return
@ -324,7 +310,6 @@ class BrowserActionActivity : AppCompatActivity() {
""".trimIndent().replace("\n", ""), null)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun getAudioButtonLocation(loopId: String) {
webview.evaluateJavascript("""
(function() {
@ -357,7 +342,6 @@ class BrowserActionActivity : AppCompatActivity() {
""".trimIndent().replace("\n", ""), null)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun doStageDownloadAudio(loopId: String) {
webview.evaluateJavascript("""
(function() {
@ -383,7 +367,6 @@ class BrowserActionActivity : AppCompatActivity() {
""".trimIndent().replace("\n", ""), null)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun typeResult(loopId: String, result: String) {
webview.evaluateJavascript("""
(function() {
@ -412,14 +395,12 @@ class BrowserActionActivity : AppCompatActivity() {
""".trimIndent().replace("\n", ""), null)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun beginSolveLoop() {
val loopId = UUID.randomUUID().toString()
currentLoopId = loopId
doStageCheckbox(loopId)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@JavascriptInterface
fun validateCaptchaCallback(result: Boolean, loopId: String) {
if (loopId != validateCurrentLoopId) return
@ -448,7 +429,6 @@ class BrowserActionActivity : AppCompatActivity() {
}
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun runValidateCaptcha(loopId: String) {
if (loopId != validateCurrentLoopId) return
@ -476,7 +456,6 @@ class BrowserActionActivity : AppCompatActivity() {
""".trimIndent().replace("\n", ""), null)
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun beginValidateCaptchaLoop() {
val loopId = UUID.randomUUID().toString()
validateCurrentLoopId = loopId

@ -6,7 +6,6 @@ import android.webkit.WebResourceResponse
import android.webkit.WebView
import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
open class HeadersInjectingWebViewClient(
activity: BrowserActionActivity,
verifyComplete: (String) -> Boolean,

@ -5,7 +5,6 @@ import android.webkit.WebResourceRequest
import androidx.annotation.RequiresApi
import okhttp3.Request
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun WebResourceRequest.toOkHttpRequest(): Request {
val request = Request.Builder()
.url(url.toString())

@ -6,17 +6,13 @@ import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.launchIn
import eu.kanade.tachiyomi.util.lang.launchInUI
import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.injectLazy
object LockActivityDelegate {
private val preferences by injectLazy<PreferencesHelper>()
val uiScope = CoroutineScope(Dispatchers.Main)
var willLock: Boolean = true
fun doLock(router: Router, animate: Boolean = false) {
@ -33,7 +29,7 @@ object LockActivityDelegate {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
.launchIn(uiScope)
.launchInUI()
}
fun onResume(activity: FragmentActivity, router: Router) {

@ -1,12 +1,10 @@
package exh.ui.lock
import android.annotation.TargetApi
import android.app.AppOpsManager
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.provider.Settings
import com.afollestad.materialdialogs.MaterialDialog
import com.elvishew.xlog.XLog
@ -55,7 +53,6 @@ fun notifyLockSecurity(
): Boolean {
return false
if (!prefs.eh_lockManually().getOrDefault() &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
!hasAccessToUsageStats(context)) {
MaterialDialog.Builder(context)
.title("Permission required")
@ -89,7 +86,6 @@ fun notifyLockSecurity(
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
fun hasAccessToUsageStats(context: Context): Boolean {
return try {
val packageManager = context.packageManager

@ -1,7 +1,6 @@
package exh.ui.login
import android.net.Uri
import android.os.Build
import android.view.LayoutInflater
import android.view.View
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")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().removeAllCookies {
launchUI {
startWebview(view)
}
CookieManager.getInstance().removeAllCookies {
launchUI {
startWebview(view)
}
} else {
CookieManager.getInstance().removeAllCookie()
startWebview(view)
}
}
}
private fun hideAdvancedOptions(view: View) {
with(view) {
binding.advancedOptions.gone()
binding.webview.visible()
binding.btnAdvanced.isEnabled = true
binding.btnCancel.isEnabled = true
}
binding.advancedOptions.gone()
binding.webview.visible()
binding.btnAdvanced.isEnabled = true
binding.btnCancel.isEnabled = true
}
fun startWebview(view: View) {
with(view) {
binding.webview.settings.javaScriptEnabled = true
binding.webview.settings.domStorageEnabled = true
binding.webview.settings.javaScriptEnabled = 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() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
Timber.d(url)
val parsedUrl = Uri.parse(url)
if (parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
// Hide distracting content
if (!parsedUrl.queryParameterNames.contains(PARAM_SKIP_INJECT))
view.evaluateJavascript(HIDE_JS, null)
binding.webview.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
Timber.d(url)
val parsedUrl = Uri.parse(url)
if (parsedUrl.host.equals("forums.e-hentai.org", ignoreCase = true)) {
// Hide distracting content
if (!parsedUrl.queryParameterNames.contains(PARAM_SKIP_INJECT))
view.evaluateJavascript(HIDE_JS, null)
// Check login result
if (parsedUrl.getQueryParameter("code")?.toInt() != 0) {
if (checkLoginCookies(url)) view.loadUrl("https://exhentai.org/")
}
} else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
// At ExHentai, check that everything worked out...
if (applyExHentaiCookies(url)) {
preferenceManager.enableExhentai().set(true)
finishLogin()
}
// Check login result
if (parsedUrl.getQueryParameter("code")?.toInt() != 0) {
if (checkLoginCookies(url)) view.loadUrl("https://exhentai.org/")
}
} else if (parsedUrl.host.equals("exhentai.org", ignoreCase = true)) {
// At ExHentai, check that everything worked out...
if (applyExHentaiCookies(url)) {
preferenceManager.enableExhentai().set(true)
finishLogin()
}
}
}

@ -18,7 +18,7 @@ class CachedField<T>(private val expiresAfterMs: Long) {
content = producer()
}
content as T
content!!
}
}
}

@ -35,12 +35,12 @@ class DeferredField<T> {
*/
suspend fun get(): T {
// 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
mutex.withLock {}
// 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) {
// Special case root
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>>>()
@ -27,7 +27,7 @@ class NakedTrieNode<T>(val key: Int, var parent: NakedTrieNode<T>?) {
stack += key + it.key.toChar() to it
}
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++
}
return current.data as T
return current.data!!
}
// Includes root