Replace more Kotlin synthetics

(cherry picked from commit 019a0f31c767c496bcc569485d5daf57fcc947eb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceComfortableGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/SourceItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryComfortableGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCompactGridHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt
#	app/src/main/java/eu/kanade/tachiyomi/widget/preference/LoginDialogPreference.kt
This commit is contained in:
arkon 2020-11-28 15:54:53 -05:00 committed by Jobobby04
parent c9c808a782
commit 9d16b0efd2
18 changed files with 166 additions and 144 deletions

View File

@ -667,13 +667,13 @@ open class BrowseSourceController(bundle: Bundle) :
* @param manga the manga to find. * @param manga the manga to find.
* @return the holder of the manga or null if it's not bound. * @return the holder of the manga or null if it's not bound.
*/ */
private fun getHolder(manga: Manga): SourceHolder? { private fun getHolder(manga: Manga): SourceHolder<*>? {
val adapter = adapter ?: return null val adapter = adapter ?: return null
adapter.allBoundViewHolders.forEach { holder -> adapter.allBoundViewHolders.forEach { holder ->
val item = adapter.getItem(holder.bindingAdapterPosition) as? SourceItem val item = adapter.getItem(holder.bindingAdapterPosition) as? SourceItem
if (item != null && item.manga.id!! == manga.id!!) { if (item != null && item.manga.id!! == manga.id!!) {
return holder as SourceHolder return holder as SourceHolder<*>
} }
} }

View File

@ -22,9 +22,9 @@ import exh.metadata.metadata.base.RaisedSearchMetadata
* @constructor creates a new catalogue holder. * @constructor creates a new catalogue holder.
*/ */
class SourceComfortableGridHolder(private val view: View, private val adapter: FlexibleAdapter<*> /* SY --> */, private val hasTitle: Boolean /* SY <-- */) : class SourceComfortableGridHolder(private val view: View, private val adapter: FlexibleAdapter<*> /* SY --> */, private val hasTitle: Boolean /* SY <-- */) :
SourceGridHolder(view, adapter) { SourceHolder<SourceComfortableGridItemBinding>(view, adapter) {
private val binding = SourceComfortableGridItemBinding.bind(view) override val binding = SourceComfortableGridItemBinding.bind(view)
/** /**
* Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this

View File

@ -28,9 +28,9 @@ import java.util.Date
* @constructor creates a new catalogue holder. * @constructor creates a new catalogue holder.
*/ */
class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleAdapter<*>) : class SourceEnhancedEHentaiListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
SourceHolder(view, adapter) { SourceHolder<SourceEnhancedEhentaiListItemBinding>(view, adapter) {
private val binding = SourceEnhancedEhentaiListItemBinding.bind(view) override val binding = SourceEnhancedEhentaiListItemBinding.bind(view)
private val favoriteColor = view.context.getResourceColor(R.attr.colorOnSurface, 0.38f) private val favoriteColor = view.context.getResourceColor(R.attr.colorOnSurface, 0.38f)
private val unfavoriteColor = view.context.getResourceColor(R.attr.colorOnSurface) private val unfavoriteColor = view.context.getResourceColor(R.attr.colorOnSurface)

View File

@ -22,9 +22,9 @@ import exh.metadata.metadata.base.RaisedSearchMetadata
* @constructor creates a new catalogue holder. * @constructor creates a new catalogue holder.
*/ */
open class SourceGridHolder(private val view: View, private val adapter: FlexibleAdapter<*>) : open class SourceGridHolder(private val view: View, private val adapter: FlexibleAdapter<*>) :
SourceHolder(view, adapter) { SourceHolder<SourceComfortableGridItemBinding>(view, adapter) {
private val binding = SourceComfortableGridItemBinding.bind(view) override val binding = SourceComfortableGridItemBinding.bind(view)
/** /**
* Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.browse.source.browse package eu.kanade.tachiyomi.ui.browse.source.browse
import android.view.View import android.view.View
import androidx.viewbinding.ViewBinding
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
@ -12,9 +13,11 @@ import exh.metadata.metadata.base.RaisedSearchMetadata
* @param view the inflated view for this holder. * @param view the inflated view for this holder.
* @param adapter the adapter handling this holder. * @param adapter the adapter handling this holder.
*/ */
abstract class SourceHolder(view: View, adapter: FlexibleAdapter<*>) : abstract class SourceHolder<VB : ViewBinding>(view: View, adapter: FlexibleAdapter<*>) :
FlexibleViewHolder(view, adapter) { FlexibleViewHolder(view, adapter) {
abstract val binding: VB
/** /**
* Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this * Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga. * holder with the given manga.

View File

@ -14,17 +14,17 @@ 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.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import exh.EH_SOURCE_ID import exh.EH_SOURCE_ID
import exh.EXH_SOURCE_ID import exh.EXH_SOURCE_ID
import exh.metadata.metadata.base.RaisedSearchMetadata import exh.metadata.metadata.base.RaisedSearchMetadata
import kotlinx.android.synthetic.main.source_compact_grid_item.view.card
import kotlinx.android.synthetic.main.source_compact_grid_item.view.gradient
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode> /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) : class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMode> /* SY --> */, private val metadata: RaisedSearchMetadata? = null /* SY <-- */) :
AbstractFlexibleItem<SourceHolder>() { AbstractFlexibleItem<SourceHolder<*>>() {
// SY --> // SY -->
val preferences: PreferencesHelper by injectLazy() val preferences: PreferencesHelper by injectLazy()
// SY <-- // SY <--
@ -41,19 +41,20 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
override fun createViewHolder( override fun createViewHolder(
view: View, view: View,
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
): SourceHolder { ): SourceHolder<*> {
return /* SY --> */ if ((manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID) && preferences.enhancedEHentaiView().get()) { return /* SY --> */ if ((manga.source == EH_SOURCE_ID || manga.source == EXH_SOURCE_ID) && preferences.enhancedEHentaiView().get()) {
SourceEnhancedEHentaiListHolder(view, adapter) SourceEnhancedEHentaiListHolder(view, adapter)
} else /* SY <-- */ when (displayMode.get()) { } else /* SY <-- */ when (displayMode.get()) {
DisplayMode.COMPACT_GRID -> { DisplayMode.COMPACT_GRID -> {
val binding = SourceCompactGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
view.apply { view.apply {
card.layoutParams = FrameLayout.LayoutParams( binding.card.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
coverHeight coverHeight
) )
gradient.layoutParams = FrameLayout.LayoutParams( binding.gradient.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
coverHeight / 2, coverHeight / 2,
Gravity.BOTTOM Gravity.BOTTOM
@ -62,10 +63,11 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
SourceGridHolder(view, adapter) SourceGridHolder(view, adapter)
} }
DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> { DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> {
val binding = SourceComfortableGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
view.apply { view.apply {
card.layoutParams = ConstraintLayout.LayoutParams( binding.card.layoutParams = ConstraintLayout.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
coverHeight coverHeight
) )
@ -80,7 +82,7 @@ class SourceItem(val manga: Manga, private val displayMode: Preference<DisplayMo
override fun bindViewHolder( override fun bindViewHolder(
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: SourceHolder, holder: SourceHolder<*>,
position: Int, position: Int,
payloads: List<Any?>? payloads: List<Any?>?
) { ) {

View File

@ -25,9 +25,9 @@ import exh.metadata.metadata.base.RaisedSearchMetadata
* @constructor creates a new catalogue holder. * @constructor creates a new catalogue holder.
*/ */
class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) : class SourceListHolder(private val view: View, adapter: FlexibleAdapter<*>) :
SourceHolder(view, adapter) { SourceHolder<SourceListItemBinding>(view, adapter) {
private val binding = SourceListItemBinding.bind(view) override val binding = SourceListItemBinding.bind(view)
private val favoriteColor = view.context.getResourceColor(R.attr.colorOnSurface, 0.38f) private val favoriteColor = view.context.getResourceColor(R.attr.colorOnSurface, 0.38f)
private val unfavoriteColor = view.context.getResourceColor(R.attr.colorOnSurface) private val unfavoriteColor = view.context.getResourceColor(R.attr.colorOnSurface)

View File

@ -278,7 +278,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
val position = adapter.indexOf(manga) val position = adapter.indexOf(manga)
if (position != -1 && !adapter.isSelected(position)) { if (position != -1 && !adapter.isSelected(position)) {
adapter.toggleSelection(position) adapter.toggleSelection(position)
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation() (recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder<*>)?.toggleActivation()
} }
} }
} }
@ -331,7 +331,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
val position = adapter.indexOf(manga) val position = adapter.indexOf(manga)
if (position != -1) { if (position != -1) {
adapter.toggleSelection(position) adapter.toggleSelection(position)
(recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder)?.toggleActivation() (recycler.findViewHolderForItemId(manga.id!!) as? LibraryHolder<*>)?.toggleActivation()
} }
} }

View File

@ -6,6 +6,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
@ -29,11 +30,13 @@ class LibraryComfortableGridHolder(
// SY --> // SY -->
private val hasTitle: Boolean private val hasTitle: Boolean
// SY <-- // SY <--
) : LibraryCompactGridHolder(view, adapter) { ) : LibraryHolder<SourceComfortableGridItemBinding>(view, adapter) {
private val binding = SourceComfortableGridItemBinding.bind(view) override val binding = SourceComfortableGridItemBinding.bind(view)
// SY --> // SY -->
var manga: Manga? = null
init { init {
binding.playLayout.clicks() binding.playLayout.clicks()
.onEach { .onEach {
@ -91,4 +94,10 @@ class LibraryComfortableGridHolder(
.dontAnimate() .dontAnimate()
.into(binding.thumbnail) .into(binding.thumbnail)
} }
// SY -->
private fun playButtonClicked() {
manga?.let { (adapter as LibraryCategoryAdapter).controller.startReading(it, (adapter as LibraryCategoryAdapter)) }
}
// SY <--
} }

View File

@ -9,7 +9,7 @@ import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.util.isLocal import eu.kanade.tachiyomi.util.isLocal
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -24,18 +24,18 @@ import reactivecircus.flowbinding.android.view.clicks
* @param listener a listener to react to single tap and long tap events. * @param listener a listener to react to single tap and long tap events.
* @constructor creates a new library holder. * @constructor creates a new library holder.
*/ */
open class LibraryCompactGridHolder( class LibraryCompactGridHolder(
private val view: View, private val view: View,
// SY --> // SY -->
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
// SY <-- // SY <--
) : LibraryHolder(view, adapter) { ) : LibraryHolder<SourceCompactGridItemBinding>(view, adapter) {
private val binding = SourceComfortableGridItemBinding.bind(view) override val binding = SourceCompactGridItemBinding.bind(view)
var manga: Manga? = null
// SY --> // SY -->
var manga: Manga? = null
init { init {
binding.playLayout.clicks() binding.playLayout.clicks()
.onEach { .onEach {
@ -92,7 +92,7 @@ open class LibraryCompactGridHolder(
} }
// SY --> // SY -->
fun playButtonClicked() { private fun playButtonClicked() {
manga?.let { (adapter as LibraryCategoryAdapter).controller.startReading(it, (adapter as LibraryCategoryAdapter)) } manga?.let { (adapter as LibraryCategoryAdapter).controller.startReading(it, (adapter as LibraryCategoryAdapter)) }
} }
// SY <-- // SY <--

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library
import android.view.View import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
import eu.davidea.viewholders.FlexibleViewHolder import eu.davidea.viewholders.FlexibleViewHolder
@ -13,13 +14,15 @@ import eu.davidea.viewholders.FlexibleViewHolder
* @param listener a listener to react to the single tap and long tap events. * @param listener a listener to react to the single tap and long tap events.
*/ */
abstract class LibraryHolder( abstract class LibraryHolder<VB : ViewBinding>(
view: View, view: View,
// SY --> // SY -->
val adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> val adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
// SY <-- // SY <--
) : FlexibleViewHolder(view, adapter) { ) : FlexibleViewHolder(view, adapter) {
abstract val binding: VB
/** /**
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga. * holder with the given manga.

View File

@ -17,6 +17,8 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode import eu.kanade.tachiyomi.data.preference.PreferenceValues.DisplayMode
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.SourceComfortableGridItemBinding
import eu.kanade.tachiyomi.databinding.SourceCompactGridItemBinding
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.NamespaceSource import eu.kanade.tachiyomi.source.online.NamespaceSource
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
@ -24,13 +26,11 @@ import exh.metadata.metadata.base.RaisedTag
import exh.source.getMainSource import exh.source.getMainSource
import exh.util.SourceTagsUtil import exh.util.SourceTagsUtil
import exh.util.getRaisedTags import exh.util.getRaisedTags
import kotlinx.android.synthetic.main.source_compact_grid_item.view.card
import kotlinx.android.synthetic.main.source_compact_grid_item.view.gradient
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Preference<DisplayMode>) : class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Preference<DisplayMode>) :
AbstractFlexibleItem<LibraryHolder>(), IFilterable<Pair<String, Boolean>> { AbstractFlexibleItem<LibraryHolder<*>>(), IFilterable<Pair<String, Boolean>> {
private val sourceManager: SourceManager = Injekt.get() private val sourceManager: SourceManager = Injekt.get()
// SY --> // SY -->
@ -56,14 +56,15 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
} }
} }
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder<*> {
return when (libraryDisplayMode.get()) { return when (libraryDisplayMode.get()) {
DisplayMode.COMPACT_GRID -> { DisplayMode.COMPACT_GRID -> {
val binding = SourceCompactGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
view.apply { view.apply {
card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) binding.card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight)
gradient.layoutParams = FrameLayout.LayoutParams( binding.gradient.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
coverHeight / 2, coverHeight / 2,
Gravity.BOTTOM Gravity.BOTTOM
@ -72,10 +73,11 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
LibraryCompactGridHolder(view, adapter) LibraryCompactGridHolder(view, adapter)
} }
DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> { DisplayMode.COMFORTABLE_GRID /* SY --> */, DisplayMode.NO_TITLE_GRID /* SY <-- */ -> {
val binding = SourceComfortableGridItemBinding.bind(view)
val parent = adapter.recyclerView as AutofitRecyclerView val parent = adapter.recyclerView as AutofitRecyclerView
val coverHeight = parent.itemWidth / 3 * 4 val coverHeight = parent.itemWidth / 3 * 4
view.apply { view.apply {
card.layoutParams = ConstraintLayout.LayoutParams( binding.card.layoutParams = ConstraintLayout.LayoutParams(
MATCH_PARENT, MATCH_PARENT,
coverHeight coverHeight
) )
@ -90,7 +92,7 @@ class LibraryItem(val manga: LibraryManga, private val libraryDisplayMode: Prefe
override fun bindViewHolder( override fun bindViewHolder(
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>,
holder: LibraryHolder, holder: LibraryHolder<*>,
position: Int, position: Int,
payloads: List<Any?>? payloads: List<Any?>?
) { ) {

View File

@ -24,15 +24,14 @@ import eu.kanade.tachiyomi.util.isLocal
* @param listener a listener to react to single tap and long tap events. * @param listener a listener to react to single tap and long tap events.
* @constructor creates a new library holder. * @constructor creates a new library holder.
*/ */
class LibraryListHolder( class LibraryListHolder(
private val view: View, private val view: View,
// SY --> // SY -->
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>> adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
// SY <-- // SY <--
) : LibraryHolder(view, adapter) { ) : LibraryHolder<SourceListItemBinding>(view, adapter) {
private val binding = SourceListItemBinding.bind(view) override val binding = SourceListItemBinding.bind(view)
/** /**
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this

View File

@ -9,16 +9,8 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.databinding.TrackSearchItemBinding
import eu.kanade.tachiyomi.util.view.inflate import eu.kanade.tachiyomi.util.view.inflate
import kotlinx.android.synthetic.main.track_search_item.view.track_search_cover
import kotlinx.android.synthetic.main.track_search_item.view.track_search_start
import kotlinx.android.synthetic.main.track_search_item.view.track_search_start_result
import kotlinx.android.synthetic.main.track_search_item.view.track_search_status
import kotlinx.android.synthetic.main.track_search_item.view.track_search_status_result
import kotlinx.android.synthetic.main.track_search_item.view.track_search_summary
import kotlinx.android.synthetic.main.track_search_item.view.track_search_title
import kotlinx.android.synthetic.main.track_search_item.view.track_search_type
import kotlinx.android.synthetic.main.track_search_item.view.track_search_type_result
class TrackSearchAdapter(context: Context) : class TrackSearchAdapter(context: Context) :
ArrayAdapter<TrackSearch>(context, R.layout.track_search_item, mutableListOf<TrackSearch>()) { ArrayAdapter<TrackSearch>(context, R.layout.track_search_item, mutableListOf<TrackSearch>()) {
@ -49,37 +41,39 @@ class TrackSearchAdapter(context: Context) :
class TrackSearchHolder(private val view: View) { class TrackSearchHolder(private val view: View) {
private val binding = TrackSearchItemBinding.bind(view)
fun onSetValues(track: TrackSearch) { fun onSetValues(track: TrackSearch) {
view.track_search_title.text = track.title binding.trackSearchTitle.text = track.title
view.track_search_summary.text = track.summary binding.trackSearchSummary.text = track.summary
GlideApp.with(view.context).clear(view.track_search_cover) GlideApp.with(view.context).clear(binding.trackSearchCover)
if (!track.cover_url.isEmpty()) { if (!track.cover_url.isEmpty()) {
GlideApp.with(view.context) GlideApp.with(view.context)
.load(track.cover_url) .load(track.cover_url)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop() .centerCrop()
.into(view.track_search_cover) .into(binding.trackSearchCover)
} }
if (track.publishing_status.isBlank()) { if (track.publishing_status.isBlank()) {
view.track_search_status.isVisible = false binding.trackSearchStatus.isVisible = false
view.track_search_status_result.isVisible = false binding.trackSearchStatusResult.isVisible = false
} else { } else {
view.track_search_status_result.text = track.publishing_status.capitalize() binding.trackSearchStatusResult.text = track.publishing_status.capitalize()
} }
if (track.publishing_type.isBlank()) { if (track.publishing_type.isBlank()) {
view.track_search_type.isVisible = false binding.trackSearchType.isVisible = false
view.track_search_type_result.isVisible = false binding.trackSearchTypeResult.isVisible = false
} else { } else {
view.track_search_type_result.text = track.publishing_type.capitalize() binding.trackSearchTypeResult.text = track.publishing_type.capitalize()
} }
if (track.start_date.isBlank()) { if (track.start_date.isBlank()) {
view.track_search_start.isVisible = false binding.trackSearchStart.isVisible = false
view.track_search_start_result.isVisible = false binding.trackSearchStartResult.isVisible = false
} else { } else {
view.track_search_start_result.text = track.start_date binding.trackSearchStartResult.text = track.start_date
} }
} }
} }

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.manga.track
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
@ -13,10 +14,8 @@ import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.databinding.TrackSearchDialogBinding
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import kotlinx.android.synthetic.main.track_search_dialog.view.progress
import kotlinx.android.synthetic.main.track_search_dialog.view.track_search
import kotlinx.android.synthetic.main.track_search_dialog.view.track_search_list
import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -29,7 +28,7 @@ import java.util.concurrent.TimeUnit
class TrackSearchDialog : DialogController { class TrackSearchDialog : DialogController {
private var dialogView: View? = null private var binding: TrackSearchDialogBinding? = null
private var adapter: TrackSearchAdapter? = null private var adapter: TrackSearchAdapter? = null
@ -53,13 +52,13 @@ class TrackSearchDialog : DialogController {
} }
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
binding = TrackSearchDialogBinding.inflate(LayoutInflater.from(activity!!))
val dialog = MaterialDialog(activity!!) val dialog = MaterialDialog(activity!!)
.customView(R.layout.track_search_dialog) .customView(view = binding!!.root)
.positiveButton(android.R.string.ok) { onPositiveButtonClick() } .positiveButton(android.R.string.ok) { onPositiveButtonClick() }
.negativeButton(android.R.string.cancel) .negativeButton(android.R.string.cancel)
.neutralButton(R.string.action_remove) { onRemoveButtonClick() } .neutralButton(R.string.action_remove) { onRemoveButtonClick() }
dialogView = dialog.view
onViewCreated(dialog.view, savedViewState) onViewCreated(dialog.view, savedViewState)
return dialog return dialog
@ -69,12 +68,12 @@ class TrackSearchDialog : DialogController {
// Create adapter // Create adapter
val adapter = TrackSearchAdapter(view.context) val adapter = TrackSearchAdapter(view.context)
this.adapter = adapter this.adapter = adapter
view.track_search_list.adapter = adapter binding!!.trackSearchList.adapter = adapter
// Set listeners // Set listeners
selectedItem = null selectedItem = null
view.track_search_list.itemClicks() binding!!.trackSearchList.itemClicks()
.onEach { position -> .onEach { position ->
selectedItem = adapter.getItem(position) selectedItem = adapter.getItem(position)
} }
@ -83,20 +82,20 @@ class TrackSearchDialog : DialogController {
// Do an initial search based on the manga's title // Do an initial search based on the manga's title
if (savedState == null) { if (savedState == null) {
val title = trackController.presenter.manga.title val title = trackController.presenter.manga.title
view.track_search.append(title) binding!!.trackSearch.append(title)
search(title) search(title)
} }
} }
override fun onDestroyView(view: View) { override fun onDestroyView(view: View) {
super.onDestroyView(view) super.onDestroyView(view)
dialogView = null binding = null
adapter = null adapter = null
} }
override fun onAttach(view: View) { override fun onAttach(view: View) {
super.onAttach(view) super.onAttach(view)
dialogView!!.track_search.textChanges() binding!!.trackSearch.textChanges()
.debounce(TimeUnit.SECONDS.toMillis(1)) .debounce(TimeUnit.SECONDS.toMillis(1))
.filter { it.isNotBlank() } .filter { it.isNotBlank() }
.onEach { search(it.toString()) } .onEach { search(it.toString()) }
@ -104,24 +103,24 @@ class TrackSearchDialog : DialogController {
} }
private fun search(query: String) { private fun search(query: String) {
val view = dialogView ?: return val binding = binding ?: return
view.progress.isVisible = true binding.progress.isVisible = true
view.track_search_list.isInvisible = true binding.trackSearchList.isInvisible = true
trackController.presenter.search(query, service) trackController.presenter.search(query, service)
} }
fun onSearchResults(results: List<TrackSearch>) { fun onSearchResults(results: List<TrackSearch>) {
selectedItem = null selectedItem = null
val view = dialogView ?: return val binding = binding ?: return
view.progress.isInvisible = true binding.progress.isInvisible = true
view.track_search_list.isVisible = true binding.trackSearchList.isVisible = true
adapter?.setItems(results) adapter?.setItems(results)
} }
fun onSearchResultsError() { fun onSearchResultsError() {
val view = dialogView ?: return val binding = binding ?: return
view.progress.isVisible = true binding.progress.isVisible = true
view.track_search_list.isInvisible = true binding.trackSearchList.isInvisible = true
adapter?.setItems(emptyList()) adapter?.setItems(emptyList())
} }

View File

@ -9,9 +9,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.preference.LoginDialogPreference import eu.kanade.tachiyomi.widget.preference.LoginDialogPreference
import kotlinx.android.synthetic.main.pref_account_login.view.login
import kotlinx.android.synthetic.main.pref_account_login.view.password
import kotlinx.android.synthetic.main.pref_account_login.view.username
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -31,38 +28,36 @@ class TrackLoginDialog(
constructor(service: TrackService, @StringRes usernameLabelRes: Int?) : constructor(service: TrackService, @StringRes usernameLabelRes: Int?) :
this(R.string.login_title, service.name, usernameLabelRes, bundleOf("key" to service.id)) this(R.string.login_title, service.name, usernameLabelRes, bundleOf("key" to service.id))
override fun setCredentialsOnView(view: View) = with(view) { override fun setCredentialsOnView(view: View) {
username.setText(service.getUsername()) binding?.username?.setText(service.getUsername())
password.setText(service.getPassword()) binding?.password?.setText(service.getPassword())
} }
override fun checkLogin() { override fun checkLogin() {
requestSubscription?.unsubscribe() requestSubscription?.unsubscribe()
v?.apply { if (binding!!.username.text.isNullOrEmpty() || binding!!.password.text.isNullOrEmpty()) {
if (username.text.isNullOrEmpty() || password.text.isNullOrEmpty()) { return
return
}
login.progress = 1
val user = username.text.toString()
val pass = password.text.toString()
requestSubscription = service.login(user, pass)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
dialog?.dismiss()
context.toast(R.string.login_success)
},
{ error ->
login.progress = -1
login.setText(R.string.unknown_error)
error.message?.let { context.toast(it) }
}
)
} }
binding!!.login.progress = 1
val user = binding!!.username.text.toString()
val pass = binding!!.password.text.toString()
requestSubscription = service.login(user, pass)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
dialog?.dismiss()
view?.context?.toast(R.string.login_success)
},
{ error ->
binding!!.login.progress = -1
binding!!.login.setText(R.string.unknown_error)
error.message?.let { view?.context?.toast(it) }
}
)
} }
override fun onDialogClosed() { override fun onDialogClosed() {

View File

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.widget.preference
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
@ -9,11 +10,9 @@ import com.afollestad.materialdialogs.customview.customView
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.dd.processbutton.iml.ActionProcessButton import com.dd.processbutton.iml.ActionProcessButton
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.PrefAccountLoginBinding
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import kotlinx.android.synthetic.main.pref_account_login.view.login
import kotlinx.android.synthetic.main.pref_account_login.view.username_label
import rx.Subscription import rx.Subscription
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -24,7 +23,7 @@ abstract class LoginDialogPreference(
bundle: Bundle? = null bundle: Bundle? = null
) : DialogController(bundle) { ) : DialogController(bundle) {
var v: View? = null var binding: PrefAccountLoginBinding? = null
private set private set
val preferences: PreferencesHelper by injectLazy() val preferences: PreferencesHelper by injectLazy()
@ -32,8 +31,9 @@ abstract class LoginDialogPreference(
var requestSubscription: Subscription? = null var requestSubscription: Subscription? = null
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
binding = PrefAccountLoginBinding.inflate(LayoutInflater.from(activity!!))
var dialog = MaterialDialog(activity!!) var dialog = MaterialDialog(activity!!)
.customView(R.layout.pref_account_login) .customView(view = binding!!.root)
.negativeButton(android.R.string.cancel) .negativeButton(android.R.string.cancel)
if (titleRes != null) { if (titleRes != null) {
@ -46,16 +46,14 @@ abstract class LoginDialogPreference(
} }
/* SY --> */ open /* SY <-- */ fun onViewCreated(view: View) { /* SY --> */ open /* SY <-- */ fun onViewCreated(view: View) {
v = view.apply { if (usernameLabelRes != null) {
if (usernameLabelRes != null) { binding!!.usernameLabel.hint = view.context.getString(usernameLabelRes)
username_label.hint = context.getString(usernameLabelRes)
}
login.setMode(ActionProcessButton.Mode.ENDLESS)
login.setOnClickListener { checkLogin() }
setCredentialsOnView(this)
} }
binding!!.login.setMode(ActionProcessButton.Mode.ENDLESS)
binding!!.login.setOnClickListener { checkLogin() }
setCredentialsOnView(view)
} }
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
@ -67,6 +65,7 @@ abstract class LoginDialogPreference(
open fun onDialogClosed() { open fun onDialogClosed() {
requestSubscription?.unsubscribe() requestSubscription?.unsubscribe()
binding = null
} }
protected abstract fun checkLogin() protected abstract fun checkLogin()

View File

@ -2,34 +2,42 @@ package exh.widget.preference
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.internal.main.DialogLayout import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
import com.dd.processbutton.iml.ActionProcessButton
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.PrefSiteLoginTwoFactorAuthBinding import eu.kanade.tachiyomi.databinding.PrefSiteLoginTwoFactorAuthBinding
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.all.MangaDex import eu.kanade.tachiyomi.source.online.all.MangaDex
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.preference.LoginDialogPreference
import exh.source.getMainSource import exh.source.getMainSource
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
class MangadexLoginDialog(bundle: Bundle? = null) : LoginDialogPreference(bundle = bundle) { class MangadexLoginDialog(bundle: Bundle? = null) : DialogController(bundle) {
val source = Injekt.get<SourceManager>().get(args.getLong("key", 0))?.getMainSource() as? MangaDex val source = Injekt.get<SourceManager>().get(args.getLong("key", 0))?.getMainSource() as? MangaDex
val service = Injekt.get<TrackManager>().mdList val service = Injekt.get<TrackManager>().mdList
val preferences: PreferencesHelper by injectLazy()
val scope = CoroutineScope(Job() + Dispatchers.Main) val scope = CoroutineScope(Job() + Dispatchers.Main)
var binding: PrefSiteLoginTwoFactorAuthBinding? = null var binding: PrefSiteLoginTwoFactorAuthBinding? = null
@ -41,31 +49,32 @@ class MangadexLoginDialog(bundle: Bundle? = null) : LoginDialogPreference(bundle
) )
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val dialog = MaterialDialog(activity!!).apply { binding = PrefSiteLoginTwoFactorAuthBinding.inflate(LayoutInflater.from(activity!!))
customView(R.layout.pref_site_login_two_factor_auth, scrollable = false) val dialog = MaterialDialog(activity!!)
} .customView(view = binding!!.root, scrollable = false)
onViewCreated(dialog.view) onViewCreated(dialog.view)
return dialog return dialog
} }
override fun onViewCreated(view: View) { fun onViewCreated(view: View) {
super.onViewCreated(view) binding!!.login.setMode(ActionProcessButton.Mode.ENDLESS)
(v as? DialogLayout?)?.contentLayout?.customView?.let { binding = PrefSiteLoginTwoFactorAuthBinding.bind(it) } binding!!.login.setOnClickListener { checkLogin() }
binding?.apply {
twoFactorCheck.setOnCheckedChangeListener { _, isChecked -> setCredentialsOnView(view)
twoFactorHolder.isVisible = isChecked
} binding!!.twoFactorCheck.setOnCheckedChangeListener { _, isChecked ->
binding!!.twoFactorHolder.isVisible = isChecked
} }
} }
override fun setCredentialsOnView(view: View) { private fun setCredentialsOnView(view: View) {
binding?.username?.setText(service.getUsername()) binding?.username?.setText(service.getUsername())
binding?.password?.setText(service.getPassword()) binding?.password?.setText(service.getPassword())
} }
override fun checkLogin() { private fun checkLogin() {
binding?.apply { binding?.apply {
if (username.text.isNullOrBlank() || password.text.isNullOrBlank() || (twoFactorCheck.isChecked && twoFactorEdit.text.isNullOrBlank())) { if (username.text.isNullOrBlank() || password.text.isNullOrBlank() || (twoFactorCheck.isChecked && twoFactorEdit.text.isNullOrBlank())) {
errorResult() errorResult()
@ -109,8 +118,16 @@ class MangadexLoginDialog(bundle: Bundle? = null) : LoginDialogPreference(bundle
} }
} }
override fun onDialogClosed() { override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onDialogClosed() super.onChangeStarted(handler, type)
if (!type.isEnter) {
onDialogClosed()
}
}
private fun onDialogClosed() {
scope.cancel()
binding = null
if (activity != null) { if (activity != null) {
(activity as? Listener)?.siteLoginDialogClosed(source!!) (activity as? Listener)?.siteLoginDialogClosed(source!!)
} else { } else {