Add additional advanced options to login screen

Add "more" button into global search results
Retry-all button is now more explicit on what was retried
Minor performance fix in hitomi search
This commit is contained in:
NerdNumber9 2018-07-08 17:53:03 -04:00
parent 30c12fc9de
commit 28d05b629f
11 changed files with 197 additions and 32 deletions

View File

@ -466,9 +466,7 @@ class Hitomi(private val context: Context)
.map { response -> .map { response ->
val doc = response.asJsoup() val doc = response.asJsoup()
val res = parsePage(doc).map { val res = parsePage(doc)
it
}
val sManga = res.map { val sManga = res.map {
SManga.create().apply { SManga.create().apply {
setUrlWithoutDomain(it.url!!) setUrlWithoutDomain(it.url!!)

View File

@ -45,8 +45,12 @@ open class BrowseCatalogueController(bundle: Bundle) :
FlexibleAdapter.EndlessScrollListener, FlexibleAdapter.EndlessScrollListener,
ChangeMangaCategoriesDialog.Listener { ChangeMangaCategoriesDialog.Listener {
constructor(source: CatalogueSource) : this(Bundle().apply { constructor(source: CatalogueSource,
searchQuery: String? = null) : this(Bundle().apply {
putLong(SOURCE_ID_KEY, source.id) putLong(SOURCE_ID_KEY, source.id)
if(searchQuery != null)
putString(SEARCH_QUERY_KEY, searchQuery)
}) })
/** /**
@ -98,7 +102,8 @@ open class BrowseCatalogueController(bundle: Bundle) :
} }
override fun createPresenter(): BrowseCataloguePresenter { override fun createPresenter(): BrowseCataloguePresenter {
return BrowseCataloguePresenter(args.getLong(SOURCE_ID_KEY)) return BrowseCataloguePresenter(args.getLong(SOURCE_ID_KEY),
args.getString(SEARCH_QUERY_KEY))
} }
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -507,6 +512,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
protected companion object { protected companion object {
const val SOURCE_ID_KEY = "sourceId" const val SOURCE_ID_KEY = "sourceId"
const val SEARCH_QUERY_KEY = "searchQuery"
} }
} }

View File

@ -30,6 +30,7 @@ import uy.kohesive.injekt.api.get
*/ */
open class BrowseCataloguePresenter( open class BrowseCataloguePresenter(
sourceId: Long, sourceId: Long,
searchQuery: String? = null,
sourceManager: SourceManager = Injekt.get(), sourceManager: SourceManager = Injekt.get(),
private val db: DatabaseHelper = Injekt.get(), private val db: DatabaseHelper = Injekt.get(),
private val prefs: PreferencesHelper = Injekt.get(), private val prefs: PreferencesHelper = Injekt.get(),
@ -44,7 +45,7 @@ open class BrowseCataloguePresenter(
/** /**
* Query from the view. * Query from the view.
*/ */
var query = "" var query = searchQuery ?: ""
private set private set
/** /**

View File

@ -5,6 +5,7 @@ import android.os.Parcelable
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.util.SparseArray import android.util.SparseArray
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.source.CatalogueSource
/** /**
* Adapter that holds the search cards. * Adapter that holds the search cards.
@ -14,6 +15,11 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
class CatalogueSearchAdapter(val controller: CatalogueSearchController) : class CatalogueSearchAdapter(val controller: CatalogueSearchController) :
FlexibleAdapter<CatalogueSearchItem>(null, controller, true) { FlexibleAdapter<CatalogueSearchItem>(null, controller, true) {
/**
* Listen for more button clicks.
*/
val moreClickListener: OnMoreClickListener = controller
/** /**
* Bundle where the view state of the holders is saved. * Bundle where the view state of the holders is saved.
*/ */
@ -68,6 +74,10 @@ class CatalogueSearchAdapter(val controller: CatalogueSearchController) :
} }
} }
interface OnMoreClickListener {
fun onMoreClick(source: CatalogueSource)
}
private companion object { private companion object {
const val HOLDER_BUNDLE_KEY = "holder_bundle" const val HOLDER_BUNDLE_KEY = "holder_bundle"
} }

View File

@ -7,11 +7,14 @@ import android.view.*
import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import kotlinx.android.synthetic.main.catalogue_global_search_controller.* import kotlinx.android.synthetic.main.catalogue_global_search_controller.*
import uy.kohesive.injekt.injectLazy
/** /**
* This controller shows and manages the different search result in global search. * This controller shows and manages the different search result in global search.
@ -20,7 +23,12 @@ import kotlinx.android.synthetic.main.catalogue_global_search_controller.*
*/ */
open class CatalogueSearchController(protected val initialQuery: String? = null) : open class CatalogueSearchController(protected val initialQuery: String? = null) :
NucleusController<CatalogueSearchPresenter>(), NucleusController<CatalogueSearchPresenter>(),
CatalogueSearchCardAdapter.OnMangaClickListener { CatalogueSearchCardAdapter.OnMangaClickListener, CatalogueSearchAdapter.OnMoreClickListener {
/**
* Application preferences.
*/
private val preferences: PreferencesHelper by injectLazy()
/** /**
* Adapter containing search results grouped by lang. * Adapter containing search results grouped by lang.
@ -185,4 +193,16 @@ open class CatalogueSearchController(protected val initialQuery: String? = null)
getHolder(source)?.setImage(manga) getHolder(source)?.setImage(manga)
} }
override fun onMoreClick(source: CatalogueSource) {
openCatalogue(source, BrowseCatalogueController(source, presenter.query))
}
/**
* Opens a catalogue with the given controller.
*/
private fun openCatalogue(source: CatalogueSource, controller: BrowseCatalogueController) {
preferences.lastUsedCatalogueSource().set(source.id)
router.pushController(controller.withFadeTransaction())
}
} }

View File

@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.util.gone
import eu.kanade.tachiyomi.util.setVectorCompat import eu.kanade.tachiyomi.util.setVectorCompat
import eu.kanade.tachiyomi.util.visible import eu.kanade.tachiyomi.util.visible
import kotlinx.android.synthetic.main.catalogue_global_search_controller_card.* import kotlinx.android.synthetic.main.catalogue_global_search_controller_card.*
import kotlinx.android.synthetic.main.catalogue_global_search_controller_card.view.*
/** /**
* Holder that binds the [CatalogueSearchItem] containing catalogue cards. * Holder that binds the [CatalogueSearchItem] containing catalogue cards.
@ -34,6 +35,13 @@ class CatalogueSearchHolder(view: View, val adapter: CatalogueSearchAdapter) :
nothing_found_icon.setVectorCompat(R.drawable.ic_search_black_112dp, nothing_found_icon.setVectorCompat(R.drawable.ic_search_black_112dp,
view.context.getResourceColor(android.R.attr.textColorHint)) view.context.getResourceColor(android.R.attr.textColorHint))
more.setOnClickListener {
val item = adapter.getItem(adapterPosition)
if (item != null) {
adapter.moreClickListener.onMoreClick(item.source)
}
}
} }
/** /**

View File

@ -204,6 +204,8 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
} }
subscriptions += eh_retry_all.clicks().subscribe { subscriptions += eh_retry_all.clicks().subscribe {
var retried = 0
viewer?.pages?.forEachIndexed { index, page -> viewer?.pages?.forEachIndexed { index, page ->
if(page.status == Page.ERROR) if(page.status == Page.ERROR)
page.status = Page.QUEUE page.status = Page.QUEUE
@ -218,9 +220,11 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
presenter.loader.loadPriorizedPage(page) presenter.loader.loadPriorizedPage(page)
else else
presenter.loader.loadPage(page) presenter.loader.loadPage(page)
retried++
} }
toast("Retrying all failed pages...") toast("Retried $retried failed pages...")
} }
subscriptions += eh_retry_all_help.clicks().subscribe { subscriptions += eh_retry_all_help.clicks().subscribe {

View File

@ -9,12 +9,16 @@ import android.webkit.CookieManager
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.jakewharton.rxbinding.view.clicks
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.EHentai import eu.kanade.tachiyomi.source.online.all.EHentai
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.gone
import eu.kanade.tachiyomi.util.invisible
import eu.kanade.tachiyomi.util.launchUI import eu.kanade.tachiyomi.util.launchUI
import eu.kanade.tachiyomi.util.visible
import exh.EXH_SOURCE_ID import exh.EXH_SOURCE_ID
import exh.uconfig.WarnConfigureDialogController import exh.uconfig.WarnConfigureDialogController
import kotlinx.android.synthetic.main.eh_activity_login.view.* import kotlinx.android.synthetic.main.eh_activity_login.view.*
@ -46,7 +50,33 @@ class LoginController : NucleusController<LoginPresenter>() {
with(view) { with(view) {
btn_cancel.setOnClickListener { router.popCurrentController() } btn_cancel.setOnClickListener { router.popCurrentController() }
btn_recheck.setOnClickListener { webview.loadUrl("https://exhentai.org/") }
btn_advanced.setOnClickListener {
advanced_options.visible()
adv_shim.visible()
webview.gone()
btn_advanced.isEnabled = false
btn_cancel.isEnabled = false
}
btn_close.setOnClickListener {
hideAdvancedOptions(this)
}
btn_recheck.setOnClickListener {
hideAdvancedOptions(this)
webview.loadUrl("https://exhentai.org/")
}
btn_alt_login.setOnClickListener {
hideAdvancedOptions(this)
webview.loadUrl("https://e-hentai.org/bounce_login.php")
}
btn_skip_restyle.setOnClickListener {
hideAdvancedOptions(this)
webview.loadUrl("https://forums.e-hentai.org/index.php?act=Login&$PARAM_SKIP_INJECT=true")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().removeAllCookies { CookieManager.getInstance().removeAllCookies {
@ -61,6 +91,16 @@ class LoginController : NucleusController<LoginPresenter>() {
} }
} }
private fun hideAdvancedOptions(view: View) {
with(view) {
advanced_options.gone()
adv_shim.gone()
webview.visible()
btn_advanced.isEnabled = true
btn_cancel.isEnabled = true
}
}
fun startWebview(view: View) { fun startWebview(view: View) {
with(view) { with(view) {
webview.settings.javaScriptEnabled = true webview.settings.javaScriptEnabled = true
@ -75,7 +115,8 @@ class LoginController : NucleusController<LoginPresenter>() {
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
view.loadUrl(HIDE_JS) if(!parsedUrl.queryParameterNames.contains(PARAM_SKIP_INJECT))
view.loadUrl(HIDE_JS)
//Check login result //Check login result
if (parsedUrl.getQueryParameter("code")?.toInt() != 0) { if (parsedUrl.getQueryParameter("code")?.toInt() != 0) {
@ -177,6 +218,8 @@ class LoginController : NucleusController<LoginPresenter>() {
} }
companion object { companion object {
const val PARAM_SKIP_INJECT = "TEH_SKIP_INJECT"
const val MEMBER_ID_COOKIE = "ipb_member_id" const val MEMBER_ID_COOKIE = "ipb_member_id"
const val PASS_HASH_COOKIE = "ipb_pass_hash" const val PASS_HASH_COOKIE = "ipb_pass_hash"
const val IGNEOUS_COOKIE = "igneous" const val IGNEOUS_COOKIE = "igneous"

View File

@ -84,7 +84,7 @@ class MetadataFetchDialog {
fun askMigration(activity: Activity, explicit: Boolean) { fun askMigration(activity: Activity, explicit: Boolean) {
var extra = "" var extra = ""
db.getLibraryMangas().asRxSingle().subscribe { db.getLibraryMangas().asRxSingle().subscribe {
if(!explicit && it.isEmpty()) { if(!explicit && it.none { isLewdSource(it.source) }) {
//Do not open dialog on startup if no manga //Do not open dialog on startup if no manga
} else { } else {
//Not logged in but have ExHentai galleries //Not logged in but have ExHentai galleries

View File

@ -18,6 +18,17 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="Title" /> tools:text="Title" />
<Button
android:id="@+id/more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="More"
style="@style/Widget.AppCompat.Button.Borderless"
app:layout_constraintBottom_toTopOf="@+id/source_card"
app:layout_constraintHeight_default="wrap"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.CardView <android.support.v7.widget.CardView
android:id="@+id/source_card" android:id="@+id/source_card"
style="@style/Theme.Widget.CardView.Item" style="@style/Theme.Widget.CardView.Item"

View File

@ -21,42 +21,106 @@
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:animateLayoutChanges="true">
<android.support.v7.widget.CardView
android:id="@+id/advanced_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/linearLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/webview"
tools:visibility="visible">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_x="0dp"
android:layout_y="0dp"
android:background="?android:attr/colorBackground"
android:orientation="vertical">
<Button
android:id="@+id/btn_recheck"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Recheck login status" />
<Button
android:id="@+id/btn_alt_login"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Alternative login page" />
<Button
android:id="@+id/btn_skip_restyle"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Skip page restyling" />
<Button
android:id="@+id/btn_close"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Close" />
</LinearLayout>
</android.support.v7.widget.CardView>
<View
android:id="@+id/adv_shim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#b5000000"
android:clickable="true"
android:visibility="gone" />
<WebView <WebView
android:id="@+id/webview" android:id="@+id/webview"
android:layout_width="0dp" android:layout_width="0dp"
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@+id/linearLayout"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" /> app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
</WebView>
<LinearLayout <LinearLayout
android:orientation="horizontal" android:id="@+id/linearLayout"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp" android:layout_width="0dp"
android:id="@+id/linearLayout"> android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<Button <Button
android:text="@android:string/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_cancel" android:id="@+id/btn_cancel"
android:layout_weight="1" style="@style/Widget.AppCompat.Button.Borderless"
style="@style/Widget.AppCompat.Button.Borderless" />
<Button
android:text="Recheck"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/btn_recheck"
android:layout_weight="1" android:layout_weight="1"
style="@style/Widget.AppCompat.Button.Borderless" /> android:text="@android:string/cancel" />
<Button
android:id="@+id/btn_advanced"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Advanced" />
</LinearLayout> </LinearLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>