Code cleanup

This commit is contained in:
Jobobby04 2020-08-04 19:32:36 -04:00
parent 29e1697d2e
commit bb87392eef
18 changed files with 107 additions and 190 deletions

View File

@ -460,10 +460,6 @@ class MigrationListController(bundle: Bundle? = null) :
return true return true
} }
override fun onDestroyView(view: View) {
super.onDestroyView(view)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.migration_list, menu) inflater.inflate(R.menu.migration_list, menu)
} }

View File

@ -93,32 +93,36 @@ class EHentaiUpdateHelper(context: Context) {
val newLastPageRead = chainsAsChapters.maxBy { it.last_page_read }?.last_page_read val newLastPageRead = chainsAsChapters.maxBy { it.last_page_read }?.last_page_read
if (existing != null) { when {
existing.read = existing.read || chapter.read existing != null -> {
existing.last_page_read = existing.last_page_read.coerceAtLeast(chapter.last_page_read) existing.read = existing.read || chapter.read
if (newLastPageRead != null && existing.last_page_read <= 0) { existing.last_page_read = existing.last_page_read.coerceAtLeast(chapter.last_page_read)
existing.last_page_read = newLastPageRead if (newLastPageRead != null && existing.last_page_read <= 0) {
} existing.last_page_read = newLastPageRead
existing.bookmark = existing.bookmark || chapter.bookmark
curChapters
} else if (chapter.date_upload > 0) { // Ignore chapters using the old system
new = true
curChapters + ChapterImpl().apply {
manga_id = accepted.manga.id
url = chapter.url
name = chapter.name
read = chapter.read
bookmark = chapter.bookmark
last_page_read = chapter.last_page_read
if (newLastPageRead != null && last_page_read <= 0) {
last_page_read = newLastPageRead
} }
existing.bookmark = existing.bookmark || chapter.bookmark
date_fetch = chapter.date_fetch curChapters
date_upload = chapter.date_upload
} }
} else curChapters chapter.date_upload > 0 -> { // Ignore chapters using the old system
new = true
curChapters + ChapterImpl().apply {
manga_id = accepted.manga.id
url = chapter.url
name = chapter.name
read = chapter.read
bookmark = chapter.bookmark
last_page_read = chapter.last_page_read
if (newLastPageRead != null && last_page_read <= 0) {
last_page_read = newLastPageRead
}
date_fetch = chapter.date_fetch
date_upload = chapter.date_upload
}
}
else -> curChapters
}
} }
.filter { it.date_upload > 0 } // Ignore chapters using the old system (filter after to prevent dupes from insert) .filter { it.date_upload > 0 } // Ignore chapters using the old system (filter after to prevent dupes from insert)
.sortedBy { it.date_upload } .sortedBy { it.date_upload }

View File

@ -127,7 +127,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
return true return true
} }
suspend fun startUpdating() { private suspend fun startUpdating() {
logger.d("Update job started!") logger.d("Update job started!")
val startTime = System.currentTimeMillis() val startTime = System.currentTimeMillis()
@ -254,7 +254,7 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
} }
// New, current // New, current
suspend fun updateEntryAndGetChapters(manga: Manga): Pair<List<Chapter>, List<Chapter>> { private suspend fun updateEntryAndGetChapters(manga: Manga): Pair<List<Chapter>, List<Chapter>> {
val source = sourceManager.get(manga.source) as? EHentai val source = sourceManager.get(manga.source) as? EHentai
?: throw GalleryNotUpdatedException(false, IllegalStateException("Missing EH-based source (${manga.source})!")) ?: throw GalleryNotUpdatedException(false, IllegalStateException("Missing EH-based source (${manga.source})!"))
@ -339,12 +339,12 @@ class EHentaiUpdateWorker : JobService(), CoroutineScope {
fun launchBackgroundTest(context: Context): String { fun launchBackgroundTest(context: Context): String {
val jobScheduler = context.jobScheduler val jobScheduler = context.jobScheduler
if (jobScheduler.schedule(context.testBackgroundJobInfo()) == JobScheduler.RESULT_FAILURE) { return if (jobScheduler.schedule(context.testBackgroundJobInfo()) == JobScheduler.RESULT_FAILURE) {
logger.e("Failed to schedule background test job!") logger.e("Failed to schedule background test job!")
return "Failed" "Failed"
} else { } else {
logger.d("Successfully scheduled background test job!") logger.d("Successfully scheduled background test job!")
return "Success" "Success"
} }
} }

View File

@ -53,7 +53,7 @@ class FavoritesSyncHelper(val context: Context) {
private val logger = XLog.tag("EHFavSync").build() private val logger = XLog.tag("EHFavSync").build()
val status = BehaviorSubject.create<FavoritesSyncStatus>(FavoritesSyncStatus.Idle(context)) val status: BehaviorSubject<FavoritesSyncStatus> = BehaviorSubject.create<FavoritesSyncStatus>(FavoritesSyncStatus.Idle(context))
@Synchronized @Synchronized
fun runSync() { fun runSync() {

View File

@ -112,7 +112,7 @@ class HitomiNozomi(
private fun BSearch(field: String, key: ByteArray, node: Node?): Single<DataPair?> { private fun BSearch(field: String, key: ByteArray, node: Node?): Single<DataPair?> {
fun compareByteArrays(dv1: ByteArray, dv2: ByteArray): Int { fun compareByteArrays(dv1: ByteArray, dv2: ByteArray): Int {
val top = Math.min(dv1.size, dv2.size) val top = dv1.size.coerceAtMost(dv2.size)
for (i in 0 until top) { for (i in 0 until top) {
val dv1i = dv1[i].toInt() and 0xFF val dv1i = dv1[i].toInt() and 0xFF
val dv2i = dv2[i].toInt() and 0xFF val dv2i = dv2[i].toInt() and 0xFF

View File

@ -50,7 +50,7 @@ class EHDebugModeOverlay(private val context: Context) : OverlayModule<String>(n
return view return view
} }
fun buildInfo() = private fun buildInfo() =
""" """
<font color='green'>===[ ${context.getString(R.string.app_name)} ]===</font><br> <font color='green'>===[ ${context.getString(R.string.app_name)} ]===</font><br>
<b>Build type:</b> ${BuildConfig.BUILD_TYPE}<br> <b>Build type:</b> ${BuildConfig.BUILD_TYPE}<br>

View File

@ -16,7 +16,7 @@ data class FlatMetadata(
) { ) {
inline fun <reified T : RaisedSearchMetadata> raise(): T = raise(T::class) inline fun <reified T : RaisedSearchMetadata> raise(): T = raise(T::class)
fun <T : RaisedSearchMetadata> raise(clazz: KClass<T>) = fun <T : RaisedSearchMetadata> raise(clazz: KClass<T>): T =
RaisedSearchMetadata.raiseFlattenGson RaisedSearchMetadata.raiseFlattenGson
.fromJson(metadata.extra, clazz.java).apply { .fromJson(metadata.extra, clazz.java).apply {
fillBaseFields(this@FlatMetadata) fillBaseFields(this@FlatMetadata)
@ -84,7 +84,7 @@ private fun <T> preparedOperationFromSingle(single: Single<T>): PreparedOperatio
} }
} }
fun DatabaseHelper.insertFlatMetadata(flatMetadata: FlatMetadata) = Completable.fromCallable { fun DatabaseHelper.insertFlatMetadata(flatMetadata: FlatMetadata): Completable = Completable.fromCallable {
require(flatMetadata.metadata.mangaId != -1L) require(flatMetadata.metadata.mangaId != -1L)
inTransaction { inTransaction {

View File

@ -1,6 +1,7 @@
package exh.metadata.metadata.base package exh.metadata.metadata.base
import android.content.Context import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import exh.metadata.forEach import exh.metadata.forEach
@ -121,7 +122,7 @@ abstract class RaisedSearchMetadata {
(this).filter { it.type != TAG_TYPE_VIRTUAL } (this).filter { it.type != TAG_TYPE_VIRTUAL }
.joinToString { (if (it.namespace != null) "${it.namespace}: " else "") + it.name } .joinToString { (if (it.namespace != null) "${it.namespace}: " else "") + it.name }
val raiseFlattenGson = GsonBuilder().create() val raiseFlattenGson: Gson = GsonBuilder().create()
fun titleDelegate(type: Int) = object : ReadWriteProperty<RaisedSearchMetadata, String?> { fun titleDelegate(type: Int) = object : ReadWriteProperty<RaisedSearchMetadata, String?> {
/** /**

View File

@ -7,7 +7,7 @@ import exh.metadata.sql.tables.SearchTitleTable
class SearchEngine { class SearchEngine {
private val queryCache = mutableMapOf<String, List<QueryComponent>>() private val queryCache = mutableMapOf<String, List<QueryComponent>>()
private fun textToSubQueries( fun textToSubQueries(
namespace: String?, namespace: String?,
component: Text? component: Text?
): Pair<String, List<String>>? { ): Pair<String, List<String>>? {
@ -69,7 +69,7 @@ class SearchEngine {
val include = mutableListOf<Pair<String, List<String>>>() val include = mutableListOf<Pair<String, List<String>>>()
val exclude = mutableListOf<Pair<String, List<String>>>() val exclude = mutableListOf<Pair<String, List<String>>>()
for (component in q) { q.forEach { component ->
val query = if (component is Text) { val query = if (component is Text) {
textToSubQueries(null, component) textToSubQueries(null, component)
} else if (component is Namespace) { } else if (component is Namespace) {

View File

@ -18,7 +18,7 @@ import uy.kohesive.injekt.injectLazy
class SmartSearchEngine( class SmartSearchEngine(
parentContext: CoroutineContext, parentContext: CoroutineContext,
val extraSearchParams: String? = null private val extraSearchParams: String? = null
) : CoroutineScope { ) : CoroutineScope {
override val coroutineContext: CoroutineContext = parentContext + Job() + Dispatchers.Default override val coroutineContext: CoroutineContext = parentContext + Job() + Dispatchers.Default

View File

@ -85,7 +85,7 @@ class EHConfigurator(val context: Context) {
configure(exhSource, hathPerks) configure(exhSource, hathPerks)
} }
fun configure(source: EHentai, hathPerks: EHHathPerksResponse) { private fun configure(source: EHentai, hathPerks: EHHathPerksResponse) {
// Delete old app profiles // Delete old app profiles
val scanReq = source.requestWithCreds().url(source.uconfigUrl).build() val scanReq = source.requestWithCreds().url(source.uconfigUrl).build()
val resp = configuratorClient.newCall(scanReq).execute().asJsoup() val resp = configuratorClient.newCall(scanReq).execute().asJsoup()

View File

@ -30,13 +30,13 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
testedGalleries = if (regex.containsMatchIn(galleries)) { testedGalleries = if (regex.containsMatchIn(galleries)) {
regex.findAll(galleries).map { galleryKeys -> regex.findAll(galleries).map { galleryKeys ->
val LinkParts = galleryKeys.value.split(".") val linkParts = galleryKeys.value.split(".")
val Link = "${if (Injekt.get<PreferencesHelper>().enableExhentai().get()) { val link = "${if (Injekt.get<PreferencesHelper>().enableExhentai().get()) {
"https://exhentai.org/g/" "https://exhentai.org/g/"
} else { } else {
"https://e-hentai.org/g/" "https://e-hentai.org/g/"
}}${LinkParts[0]}/${LinkParts[1].replace(":", "")}" }}${linkParts[0]}/${linkParts[1].replace(":", "")}"
Link link
}.joinToString(separator = "\n") }.joinToString(separator = "\n")
} else { } else {
galleries galleries

View File

@ -22,6 +22,7 @@ import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.system.setDefaultSettings
import exh.source.DelegatedHttpSource import exh.source.DelegatedHttpSource
import exh.util.melt import exh.util.melt
import java.io.Serializable import java.io.Serializable
@ -33,7 +34,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody
import rx.Observable import rx.Observable
import rx.Single import rx.Single
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
@ -81,7 +82,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)
@Suppress("NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE") @Suppress("NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE", "UNCHECKED_CAST")
val verifyComplete = if (source != null) { 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,8 +107,7 @@ class BrowserActionActivity : AppCompatActivity() {
cm.setCookie(url, cookieString) cm.setCookie(url, cookieString)
} }
webview.settings.javaScriptEnabled = true webview.setDefaultSettings()
webview.settings.domStorageEnabled = true
headers.entries.find { it.key.equals("user-agent", true) }?.let { headers.entries.find { it.key.equals("user-agent", true) }?.let {
webview.settings.userAgentString = it.value webview.settings.userAgentString = it.value
} }
@ -277,7 +277,7 @@ class BrowserActionActivity : AppCompatActivity() {
} }
} }
fun performRecognize(url: String): Single<String> { private fun performRecognize(url: String): Single<String> {
return credentialsObservable.flatMap { token -> return credentialsObservable.flatMap { token ->
httpClient.newCall( httpClient.newCall(
Request.Builder() Request.Builder()
@ -304,7 +304,11 @@ class BrowserActionActivity : AppCompatActivity() {
.addFormDataPart( .addFormDataPart(
"audio.mp3", "audio.mp3",
"audio.mp3", "audio.mp3",
RequestBody.create("audio/mp3".toMediaTypeOrNull(), audioFile) audioFile.toRequestBody(
"audio/mp3".toMediaTypeOrNull(),
0,
audioFile.size
)
) )
.build() .build()
) )
@ -315,7 +319,7 @@ class BrowserActionActivity : AppCompatActivity() {
}.toSingle() }.toSingle()
} }
fun doStageCheckbox(loopId: String) { private fun doStageCheckbox(loopId: String) {
if (loopId != currentLoopId) return if (loopId != currentLoopId) return
webview.evaluateJavascript( webview.evaluateJavascript(
@ -346,7 +350,7 @@ class BrowserActionActivity : AppCompatActivity() {
) )
} }
fun getAudioButtonLocation(loopId: String) { private fun getAudioButtonLocation(loopId: String) {
webview.evaluateJavascript( webview.evaluateJavascript(
""" """
(function() { (function() {
@ -381,7 +385,7 @@ class BrowserActionActivity : AppCompatActivity() {
) )
} }
fun doStageDownloadAudio(loopId: String) { private fun doStageDownloadAudio(loopId: String) {
webview.evaluateJavascript( webview.evaluateJavascript(
""" """
(function() { (function() {
@ -409,7 +413,7 @@ class BrowserActionActivity : AppCompatActivity() {
) )
} }
fun typeResult(loopId: String, result: String) { private fun typeResult(loopId: String, result: String) {
webview.evaluateJavascript( webview.evaluateJavascript(
""" """
(function() { (function() {
@ -478,7 +482,7 @@ class BrowserActionActivity : AppCompatActivity() {
} }
} }
fun runValidateCaptcha(loopId: String) { private fun runValidateCaptcha(loopId: String) {
if (loopId != validateCurrentLoopId) return if (loopId != validateCurrentLoopId) return
webview.evaluateJavascript( webview.evaluateJavascript(

View File

@ -93,13 +93,13 @@ class InterceptActivity : BaseActivity<EhActivityInterceptBinding>() {
private val galleryAdder = GalleryAdder() private val galleryAdder = GalleryAdder()
val status = BehaviorSubject.create<InterceptResult>(InterceptResult.Idle()) val status: BehaviorSubject<InterceptResult> = BehaviorSubject.create<InterceptResult>(InterceptResult.Idle)
@Synchronized @Synchronized
fun loadGallery(gallery: String) { fun loadGallery(gallery: String) {
// Do not load gallery if already loading // Do not load gallery if already loading
if (status.value is InterceptResult.Idle) { if (status.value is InterceptResult.Idle) {
status.onNext(InterceptResult.Loading()) status.onNext(InterceptResult.Loading)
// Load gallery async // Load gallery async
thread { thread {
@ -119,8 +119,8 @@ class InterceptActivity : BaseActivity<EhActivityInterceptBinding>() {
} }
sealed class InterceptResult { sealed class InterceptResult {
class Idle : InterceptResult() object Idle : InterceptResult()
class Loading : InterceptResult() object Loading : InterceptResult()
data class Success(val mangaId: Long) : InterceptResult() data class Success(val mangaId: Long) : InterceptResult()
data class Failure(val reason: String) : InterceptResult() data class Failure(val reason: String) : InterceptResult()
} }

View File

@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.databinding.EhActivityLoginBinding
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.setDefaultSettings
import exh.uconfig.WarnConfigureDialogController import exh.uconfig.WarnConfigureDialogController
import java.net.HttpCookie import java.net.HttpCookie
import timber.log.Timber import timber.log.Timber
@ -39,53 +40,50 @@ class LoginController : NucleusController<EhActivityLoginBinding, LoginPresenter
override fun onViewCreated(view: View) { override fun onViewCreated(view: View) {
super.onViewCreated(view) super.onViewCreated(view)
with(view) { binding.btnCancel.setOnClickListener { router.popCurrentController() }
binding.btnCancel.setOnClickListener { router.popCurrentController() }
binding.btnAdvanced.setOnClickListener { binding.btnAdvanced.setOnClickListener {
binding.advancedOptions.isVisible = true binding.advancedOptions.isVisible = true
binding.webview.isVisible = false binding.webview.isVisible = false
binding.btnAdvanced.isEnabled = false binding.btnAdvanced.isEnabled = false
binding.btnCancel.isEnabled = false binding.btnCancel.isEnabled = false
} }
binding.btnClose.setOnClickListener { binding.btnClose.setOnClickListener {
hideAdvancedOptions(this) hideAdvancedOptions()
} }
binding.btnRecheck.setOnClickListener { binding.btnRecheck.setOnClickListener {
hideAdvancedOptions(this) hideAdvancedOptions()
binding.webview.loadUrl("https://exhentai.org/") binding.webview.loadUrl("https://exhentai.org/")
} }
binding.btnAltLogin.setOnClickListener { binding.btnAltLogin.setOnClickListener {
hideAdvancedOptions(this) hideAdvancedOptions()
binding.webview.loadUrl("https://e-hentai.org/bounce_login.php") binding.webview.loadUrl("https://e-hentai.org/bounce_login.php")
} }
binding.btnSkipRestyle.setOnClickListener { binding.btnSkipRestyle.setOnClickListener {
hideAdvancedOptions(this) hideAdvancedOptions()
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")
} }
CookieManager.getInstance().removeAllCookies { CookieManager.getInstance().removeAllCookies {
launchUI { launchUI {
startWebview(view) startWebview()
}
} }
} }
} }
private fun hideAdvancedOptions(view: View) { private fun hideAdvancedOptions() {
binding.advancedOptions.isVisible = false binding.advancedOptions.isVisible = false
binding.webview.isVisible = true binding.webview.isVisible = true
binding.btnAdvanced.isEnabled = true binding.btnAdvanced.isEnabled = true
binding.btnCancel.isEnabled = true binding.btnCancel.isEnabled = true
} }
fun startWebview(view: View) { private fun startWebview() {
binding.webview.settings.javaScriptEnabled = true binding.webview.setDefaultSettings()
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")
@ -169,9 +167,9 @@ class LoginController : NucleusController<EhActivityLoginBinding, LoginPresenter
return false return false
} }
fun getCookies(url: String): List<HttpCookie>? = private fun getCookies(url: String): List<HttpCookie>? =
CookieManager.getInstance().getCookie(url)?.let { CookieManager.getInstance().getCookie(url)?.let { cookie ->
it.split("; ").flatMap { cookie.split("; ").flatMap {
HttpCookie.parse(it) HttpCookie.parse(it)
} }
} }

View File

@ -13,18 +13,14 @@ import eu.kanade.tachiyomi.ui.browse.source.SourceController
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartSearchBinding, SmartSearchPresenter>(), CoroutineScope { class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartSearchBinding, SmartSearchPresenter>() {
override val coroutineContext = Job() + Dispatchers.Main
private val sourceManager: SourceManager by injectLazy() private val sourceManager: SourceManager by injectLazy()
private val source = sourceManager.get(bundle?.getLong(ARG_SOURCE_ID, -1) ?: -1) as? CatalogueSource private val source = sourceManager.get(bundle?.getLong(ARG_SOURCE_ID, -1) ?: -1) as? CatalogueSource
@ -55,7 +51,7 @@ class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartS
// Init presenter now to resolve threading issues // Init presenter now to resolve threading issues
presenter presenter
launch(Dispatchers.Default) { scope.launch(Dispatchers.Default) {
for (event in presenter.smartSearchChannel) { for (event in presenter.smartSearchChannel) {
if (event is SmartSearchPresenter.SearchResults.Found) { if (event is SmartSearchPresenter.SearchResults.Found) {
val transaction = MangaController(event.manga, true, smartSearchConfig).withFadeTransaction() val transaction = MangaController(event.manga, true, smartSearchConfig).withFadeTransaction()
@ -81,7 +77,7 @@ class SmartSearchController(bundle: Bundle? = null) : NucleusController<EhSmartS
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
cancel() scope.cancel()
} }
companion object { companion object {

View File

@ -3,7 +3,6 @@ package exh.ui.smartsearch
import android.os.Bundle import android.os.Bundle
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.SourceController import eu.kanade.tachiyomi.ui.browse.source.SourceController
import exh.smartsearch.SmartSearchEngine import exh.smartsearch.SmartSearchEngine
@ -16,19 +15,19 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class SmartSearchPresenter(private val source: CatalogueSource?, private val config: SourceController.SmartSearchConfig?) : class SmartSearchPresenter(private val source: CatalogueSource?, private val config: SourceController.SmartSearchConfig?) :
BasePresenter<SmartSearchController>(), CoroutineScope { BasePresenter<SmartSearchController>() {
override val coroutineContext = Job() + Dispatchers.Main val scope = CoroutineScope(Job() + Dispatchers.Main)
val smartSearchChannel = Channel<SearchResults>() val smartSearchChannel = Channel<SearchResults>()
private val smartSearchEngine = SmartSearchEngine(coroutineContext) private val smartSearchEngine = SmartSearchEngine(scope.coroutineContext)
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
if (source != null && config != null) { if (source != null && config != null) {
launch(Dispatchers.Default) { scope.launch(Dispatchers.Default) {
val result = try { val result = try {
val resultManga = smartSearchEngine.smartSearch(source, config.origTitle) val resultManga = smartSearchEngine.smartSearch(source, config.origTitle)
if (resultManga != null) { if (resultManga != null) {
@ -53,11 +52,9 @@ class SmartSearchPresenter(private val source: CatalogueSource?, private val con
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
cancel() scope.cancel()
} }
data class SearchEntry(val manga: SManga, val dist: Double)
sealed class SearchResults { sealed class SearchResults {
data class Found(val manga: Manga) : SearchResults() data class Found(val manga: Manga) : SearchResults()
object NotFound : SearchResults() object NotFound : SearchResults()

View File

@ -2,9 +2,7 @@ package exh.util
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.annotation.Px import androidx.annotation.Px
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup import com.google.android.material.chip.ChipGroup
@ -14,65 +12,6 @@ import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_LIGHT
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_NORMAL import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_NORMAL
import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_WEAK import exh.metadata.metadata.EHentaiSearchMetadata.Companion.TAG_TYPE_WEAK
inline val View.marginTop: Int
get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.topMargin ?: 0
inline val View.marginBottom: Int
get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.bottomMargin ?: 0
inline val View.marginRight: Int
get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.rightMargin ?: 0
inline val View.marginLeft: Int
get() = (layoutParams as? ViewGroup.MarginLayoutParams)?.leftMargin ?: 0
fun View.doOnApplyWindowInsets(f: (View, WindowInsets, ViewPaddingState) -> Unit) {
// Create a snapshot of the view's padding state
val paddingState = createStateForView(this)
setOnApplyWindowInsetsListener { v, insets ->
f(v, insets, paddingState)
insets
}
requestApplyInsetsWhenAttached()
}
object ControllerViewWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
v.updateLayoutParams<FrameLayout.LayoutParams> {
val attrsArray = intArrayOf(android.R.attr.actionBarSize)
val array = v.context.obtainStyledAttributes(attrsArray)
topMargin = insets.systemWindowInsetTop + array.getDimensionPixelSize(0, 0)
array.recycle()
}
return insets
}
}
fun View.requestApplyInsetsWhenAttached() {
if (isAttachedToWindow) {
requestApplyInsets()
} else {
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
v.requestApplyInsets()
}
override fun onViewDetachedFromWindow(v: View) = Unit
})
}
}
inline fun <reified T : ViewGroup.LayoutParams> View.updateLayoutParams(block: T.() -> Unit) {
val params = layoutParams as T
block(params)
layoutParams = params
}
fun View.applyWindowInsetsForController() {
setOnApplyWindowInsetsListener(ControllerViewWindowInsetsListener)
requestApplyInsetsWhenAttached()
}
inline fun View.updatePaddingRelative( inline fun View.updatePaddingRelative(
@Px start: Int = paddingStart, @Px start: Int = paddingStart,
@Px top: Int = paddingTop, @Px top: Int = paddingTop,
@ -82,24 +21,6 @@ inline fun View.updatePaddingRelative(
setPaddingRelative(start, top, end, bottom) setPaddingRelative(start, top, end, bottom)
} }
private fun createStateForView(view: View) = ViewPaddingState(
view.paddingLeft,
view.paddingTop,
view.paddingRight,
view.paddingBottom,
view.paddingStart,
view.paddingEnd
)
data class ViewPaddingState(
val left: Int,
val top: Int,
val right: Int,
val bottom: Int,
val start: Int,
val end: Int
)
object RecyclerWindowInsetsListener : View.OnApplyWindowInsetsListener { object RecyclerWindowInsetsListener : View.OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets { override fun onApplyWindowInsets(v: View, insets: WindowInsets): WindowInsets {
v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom) v.updatePaddingRelative(bottom = insets.systemWindowInsetBottom)