Get Started on new Grid, only layout left

This commit is contained in:
Jobobby04 2020-05-23 15:55:24 -04:00
parent 2c0d96917f
commit ccbe240846
14 changed files with 417 additions and 55 deletions

View File

@ -73,7 +73,7 @@ object PreferenceKeys {
const val lastUsedCategory = "last_used_category" const val lastUsedCategory = "last_used_category"
const val catalogueAsList = "pref_display_catalogue_as_list" const val catalogueViewSetting = "pref_display_catalogue_view_setting"
const val enabledLanguages = "source_languages" const val enabledLanguages = "source_languages"
@ -137,7 +137,7 @@ object PreferenceKeys {
const val downloadNewCategories = "download_new_categories" const val downloadNewCategories = "download_new_categories"
const val libraryAsList = "pref_display_library_as_list" const val libraryViewSetting = "pref_display_library_view_setting"
const val lang = "app_language" const val lang = "app_language"

View File

@ -143,7 +143,7 @@ class PreferencesHelper(val context: Context) {
fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0) fun lastVersionCode() = flowPrefs.getInt("last_version_code", 0)
fun catalogueAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false) fun catalogueViewSetting() = flowPrefs.getInt(Keys.catalogueViewSetting, 0)
fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("all", "en", Locale.getDefault().language)) fun enabledLanguages() = flowPrefs.getStringSet(Keys.enabledLanguages, setOf("all", "en", Locale.getDefault().language))
@ -191,7 +191,7 @@ class PreferencesHelper(val context: Context) {
fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0) fun libraryUpdatePrioritization() = flowPrefs.getInt(Keys.libraryUpdatePrioritization, 0)
fun libraryAsList() = flowPrefs.getBoolean(Keys.libraryAsList, false) fun libraryViewSetting() = flowPrefs.getInt(Keys.libraryViewSetting, 0)
fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false) fun downloadBadge() = flowPrefs.getBoolean(Keys.downloadBadge, false)

View File

@ -314,7 +314,7 @@ open class BrowseSourceController(bundle: Bundle) :
binding.catalogueView.removeView(oldRecycler) binding.catalogueView.removeView(oldRecycler)
} }
val recycler = if (presenter.isListMode) { val recycler = if (presenter.mode == 1) {
RecyclerView(view.context).apply { RecyclerView(view.context).apply {
id = R.id.recycler id = R.id.recycler
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
@ -332,7 +332,7 @@ open class BrowseSourceController(bundle: Bundle) :
(layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { (layoutManager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int { override fun getSpanSize(position: Int): Int {
return when (adapter?.getItemViewType(position)) { return when (adapter?.getItemViewType(position)) {
R.layout.source_grid_item, null -> 1 R.layout.source_grid_item, R.layout.source_comfortable_grid_item, null -> 1
else -> spanCount else -> spanCount
} }
} }
@ -399,10 +399,10 @@ open class BrowseSourceController(bundle: Bundle) :
// Show next display mode // Show next display mode
menu.findItem(R.id.action_display_mode).apply { menu.findItem(R.id.action_display_mode).apply {
val icon = if (presenter.isListMode) { val icon = if (presenter.mode == 0) {
R.drawable.ic_view_module_24dp
} else {
R.drawable.ic_view_list_24dp R.drawable.ic_view_list_24dp
} else {
R.drawable.ic_view_module_24dp
} }
setIcon(icon) setIcon(icon)
} }
@ -583,7 +583,7 @@ open class BrowseSourceController(bundle: Bundle) :
val adapter = adapter ?: return val adapter = adapter ?: return
presenter.swapDisplayMode() presenter.swapDisplayMode()
val isListMode = presenter.isListMode val isListMode = presenter.mode == 1
activity?.invalidateOptionsMenu() activity?.invalidateOptionsMenu()
setupRecycler(view) setupRecycler(view)
if (!isListMode || !view.context.connectivityManager.isActiveNetworkMetered) { if (!isListMode || !view.context.connectivityManager.isActiveNetworkMetered) {

View File

@ -37,6 +37,12 @@ import eu.kanade.tachiyomi.ui.browse.source.filter.TriStateSectionItem
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
import exh.EXHSavedSearch import exh.EXHSavedSearch
import java.lang.RuntimeException import java.lang.RuntimeException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.subscribe
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
@ -100,7 +106,7 @@ open class BrowseSourcePresenter(
/** /**
* Whether the view is in list mode or not. * Whether the view is in list mode or not.
*/ */
var isListMode: Boolean = false var mode: Int = 0
private set private set
/** /**
@ -118,6 +124,11 @@ open class BrowseSourcePresenter(
*/ */
private var initializerSubscription: Subscription? = null private var initializerSubscription: Subscription? = null
/**
* Scope to watch the view setting
*/
private val scope = CoroutineScope(Job() + Dispatchers.Default)
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
@ -129,10 +140,9 @@ open class BrowseSourcePresenter(
query = savedState.getString(::query.name, "") query = savedState.getString(::query.name, "")
} }
add( prefs.catalogueViewSetting().asFlow()
prefs.catalogueAsList().asObservable() .onEach { setDisplayMode(it) }
.subscribe { setDisplayMode(it) } .launchIn(scope)
)
restartPager() restartPager()
} }
@ -161,7 +171,7 @@ open class BrowseSourcePresenter(
val sourceId = source.id val sourceId = source.id
val catalogueAsList = prefs.catalogueAsList() val catalogueAsList = prefs.catalogueViewSetting()
// Prepare the pager. // Prepare the pager.
pagerSubscription?.let { remove(it) } pagerSubscription?.let { remove(it) }
@ -210,10 +220,10 @@ open class BrowseSourcePresenter(
/** /**
* Sets the display mode. * Sets the display mode.
* *
* @param asList whether the current mode is in list or not. * @param mode whether the current mode is in list or not.
*/ */
private fun setDisplayMode(asList: Boolean) { private fun setDisplayMode(mode: Int) {
isListMode = asList this.mode = mode
subscribeToMangaInitializer() subscribeToMangaInitializer()
} }
@ -302,7 +312,13 @@ open class BrowseSourcePresenter(
* Changes the active display mode. * Changes the active display mode.
*/ */
fun swapDisplayMode() { fun swapDisplayMode() {
prefs.catalogueAsList().set(!isListMode) prefs.catalogueViewSetting().set(
when (mode) {
0 -> 1
1 -> 2
else -> 0
}
)
} }
/** /**

View File

@ -0,0 +1,56 @@
package eu.kanade.tachiyomi.ui.browse.source.browse
import android.view.View
import com.bumptech.glide.load.engine.DiskCacheStrategy
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
import eu.kanade.tachiyomi.widget.StateImageViewTarget
import kotlinx.android.synthetic.main.source_comfortable_grid_item.card
import kotlinx.android.synthetic.main.source_comfortable_grid_item.progress
import kotlinx.android.synthetic.main.source_comfortable_grid_item.thumbnail
import kotlinx.android.synthetic.main.source_comfortable_grid_item.title
/**
* Class used to hold the displayed data of a manga in the catalogue, like the cover or the title.
* All the elements from the layout file "item_source_grid" are available in this class.
*
* @param view the inflated view for this holder.
* @param adapter the adapter handling this holder.
* @constructor creates a new catalogue holder.
*/
class SourceComfortableGridHolder(private val view: View, private val adapter: FlexibleAdapter<*>) :
SourceHolder(view, adapter) {
/**
* Method called from [CatalogueAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga.
*
* @param manga the manga to bind.
*/
override fun onSetValues(manga: Manga) {
// Set manga title
title.text = manga.title
// Set alpha of thumbnail.
thumbnail.alpha = if (manga.favorite) 0.3f else 1.0f
setImage(manga)
}
override fun setImage(manga: Manga) {
// Setting this via XML doesn't work
card.clipToOutline = true
GlideApp.with(view.context).clear(thumbnail)
if (!manga.thumbnail_url.isNullOrEmpty()) {
GlideApp.with(view.context)
.load(manga.toMangaThumbnail())
.diskCacheStrategy(DiskCacheStrategy.DATA)
.centerCrop()
.placeholder(android.R.color.transparent)
.into(StateImageViewTarget(thumbnail, progress))
}
}
}

View File

@ -5,25 +5,24 @@ import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.f2prateek.rx.preferences.Preference import com.tfcporciuncula.flow.Preference
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import eu.davidea.flexibleadapter.items.IFlexible import eu.davidea.flexibleadapter.items.IFlexible
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.getOrDefault
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.android.synthetic.main.source_grid_item.view.card import kotlinx.android.synthetic.main.source_grid_item.view.card
import kotlinx.android.synthetic.main.source_grid_item.view.gradient import kotlinx.android.synthetic.main.source_grid_item.view.gradient
class SourceItem(val manga: Manga, private val catalogueAsList: Preference<Boolean>) : class SourceItem(val manga: Manga, private val catalogueAsList: Preference<Int>) :
AbstractFlexibleItem<SourceHolder>() { AbstractFlexibleItem<SourceHolder>() {
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return if (catalogueAsList.getOrDefault()) { return when (catalogueAsList.get()) {
R.layout.source_list_item 0 -> R.layout.source_grid_item
} else { 1 -> R.layout.source_list_item
R.layout.source_grid_item else -> R.layout.source_comfortable_grid_item
} }
} }
@ -33,15 +32,28 @@ class SourceItem(val manga: Manga, private val catalogueAsList: Preference<Boole
): SourceHolder { ): SourceHolder {
val parent = adapter.recyclerView val parent = adapter.recyclerView
return if (parent is AutofitRecyclerView) { return if (parent is AutofitRecyclerView) {
view.apply { if (catalogueAsList.get() == 0) {
card.layoutParams = FrameLayout.LayoutParams( view.apply {
MATCH_PARENT, parent.itemWidth / 3 * 4 card.layoutParams = FrameLayout.LayoutParams(
) MATCH_PARENT, parent.itemWidth / 3 * 4
gradient.layoutParams = FrameLayout.LayoutParams( )
MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM gradient.layoutParams = FrameLayout.LayoutParams(
) MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM
)
}
SourceGridHolder(view, adapter)
} else {
view.apply {
card.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT, parent.itemWidth / 3 * 5
)
// inside.layoutParams = FrameLayout.LayoutParams(parent.height / 3 * 4, MATCH_PARENT)
gradient.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT, parent.itemWidth / 3 * 4 / 2, Gravity.BOTTOM
)
}
SourceComfortableGridHolder(view, adapter)
} }
SourceGridHolder(view, adapter)
} else { } else {
SourceListHolder(view, adapter) SourceListHolder(view, adapter)
} }

View File

@ -93,7 +93,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
fun onCreate(controller: LibraryController) { fun onCreate(controller: LibraryController) {
this.controller = controller this.controller = controller
recycler = if (preferences.libraryAsList().get()) { recycler = if (preferences.libraryViewSetting().get() == 1) {
(swipe_refresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply { (swipe_refresh.inflate(R.layout.library_list_recycler) as RecyclerView).apply {
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
} }

View File

@ -0,0 +1,68 @@
package eu.kanade.tachiyomi.ui.library
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.load.engine.DiskCacheStrategy
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.IFlexible
import eu.kanade.tachiyomi.data.glide.GlideApp
import eu.kanade.tachiyomi.data.glide.toMangaThumbnail
import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.source_comfortable_grid_item.card
import kotlinx.android.synthetic.main.source_comfortable_grid_item.download_text
import kotlinx.android.synthetic.main.source_comfortable_grid_item.local_text
import kotlinx.android.synthetic.main.source_comfortable_grid_item.thumbnail
import kotlinx.android.synthetic.main.source_comfortable_grid_item.title
import kotlinx.android.synthetic.main.source_comfortable_grid_item.unread_text
/**
* Class used to hold the displayed data of a manga in the library, like the cover or the title.
* All the elements from the layout file "item_source_grid" are available in this class.
*
* @param view the inflated view for this holder.
* @param adapter the adapter handling this holder.
* @param listener a listener to react to single tap and long tap events.
* @constructor creates a new library holder.
*/
class LibraryComfortableGridHolder(
private val view: View,
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
) : LibraryHolder(view, adapter) {
/**
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
* holder with the given manga.
*
* @param item the manga item to bind.
*/
override fun onSetValues(item: LibraryItem) {
// Update the title of the manga.
title.text = item.manga.title
// Update the unread count and its visibility.
with(unread_text) {
visibleIf { item.unreadCount > 0 }
text = item.unreadCount.toString()
}
// Update the download count and its visibility.
with(download_text) {
visibleIf { item.downloadCount > 0 }
text = item.downloadCount.toString()
}
// set local visibility if its local manga
local_text.visibleIf { item.manga.isLocal() }
// Setting this via XML doesn't work
card.clipToOutline = true
// Update the cover.
GlideApp.with(view.context).clear(thumbnail)
GlideApp.with(view.context)
.load(item.manga.toMangaThumbnail())
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.centerCrop()
.dontAnimate()
.into(thumbnail)
}
}

View File

@ -3,7 +3,10 @@ package eu.kanade.tachiyomi.ui.library
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.tfcporciuncula.flow.Preference import com.tfcporciuncula.flow.Preference
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -16,13 +19,17 @@ 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.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import exh.util.updateLayoutParams
import kotlinx.android.synthetic.main.source_comfortable_grid_item.view.constraint_layout
import kotlinx.android.synthetic.main.source_grid_item.view.card import kotlinx.android.synthetic.main.source_grid_item.view.card
import kotlinx.android.synthetic.main.source_grid_item.view.gradient import kotlinx.android.synthetic.main.source_grid_item.view.gradient
import kotlinx.android.synthetic.main.source_grid_item.view.thumbnail
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 libraryAsList: Preference<Boolean>) : class LibraryItem(val manga: LibraryManga, private val libraryViewSetting: Preference<Int>) :
AbstractFlexibleItem<LibraryHolder>(), IFilterable<String> { AbstractFlexibleItem<LibraryHolder>(), IFilterable<String> {
private val sourceManager: SourceManager = Injekt.get() private val sourceManager: SourceManager = Injekt.get()
@ -33,24 +40,58 @@ class LibraryItem(val manga: LibraryManga, private val libraryAsList: Preference
var unreadCount = -1 var unreadCount = -1
override fun getLayoutRes(): Int { override fun getLayoutRes(): Int {
return if (libraryAsList.get()) { return when (libraryViewSetting.get()) {
R.layout.source_list_item 0 -> R.layout.source_grid_item
} else { 1 -> R.layout.source_list_item
R.layout.source_grid_item else -> R.layout.source_comfortable_grid_item
} }
} }
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder { override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>): LibraryHolder {
val parent = adapter.recyclerView val parent = adapter.recyclerView
return if (parent is AutofitRecyclerView) { return if (parent is AutofitRecyclerView) {
view.apply { if (libraryViewSetting.get() == 0) {
val coverHeight = parent.itemWidth / 3 * 4 view.apply {
card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight) val coverHeight = parent.itemWidth / 3 * 4
gradient.layoutParams = FrameLayout.LayoutParams( card.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight)
MATCH_PARENT, coverHeight / 2, Gravity.BOTTOM gradient.layoutParams = FrameLayout.LayoutParams(
) MATCH_PARENT, coverHeight / 2, Gravity.BOTTOM
)
}
LibraryGridHolder(view, adapter)
} else {
view.apply {
val coverHeight = parent.itemWidth / 3 * 4
gradient.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT,
coverHeight * (66 / 100),
Gravity.BOTTOM
)
card.updateLayoutParams<ConstraintLayout.LayoutParams> {
bottomMargin = 6.dpToPx
}
constraint_layout.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT, WRAP_CONTENT
)
thumbnail.maxHeight = Int.MAX_VALUE
thumbnail.minimumHeight = 0
constraint_layout.minHeight = 0
thumbnail.scaleType = ImageView.ScaleType.CENTER_CROP
thumbnail.adjustViewBounds = false
thumbnail.layoutParams = FrameLayout.LayoutParams(
MATCH_PARENT,
(parent.itemWidth / 3f * 3.7f).toInt()
)
// .layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, coverHeight)
// gradient.layoutParams = FrameLayout.LayoutParams(
// MATCH_PARENT, coverHeight / 2, Gravity.BOTTOM
// )
}
LibraryComfortableGridHolder(view, adapter)
} }
LibraryGridHolder(view, adapter)
} else { } else {
LibraryListHolder(view, adapter) LibraryListHolder(view, adapter)
} }

View File

@ -301,7 +301,7 @@ class LibraryPresenter(
* value. * value.
*/ */
private fun getLibraryMangasObservable(): Observable<LibraryMap> { private fun getLibraryMangasObservable(): Observable<LibraryMap> {
val libraryAsList = preferences.libraryAsList() val libraryAsList = preferences.libraryViewSetting()
return db.getLibraryMangas().asRxObservable() return db.getLibraryMangas().asRxObservable()
.map { list -> .map { list ->
list.map { LibraryItem(it, libraryAsList) }.groupBy { it.manga.category } list.map { LibraryItem(it, libraryAsList) }.groupBy { it.manga.category }

View File

@ -220,16 +220,18 @@ class LibrarySettingsSheet(
inner class DisplayGroup : Group { inner class DisplayGroup : Group {
private val grid = Item.Radio(R.string.action_display_grid, this) private val grid = Item.Radio(R.string.action_display_grid, this)
private val comfortableGrid = Item.Radio(R.string.action_display_comfortable_grid, this)
private val list = Item.Radio(R.string.action_display_list, this) private val list = Item.Radio(R.string.action_display_list, this)
override val header = null override val header = null
override val items = listOf(grid, list) override val items = listOf(grid, comfortableGrid, list)
override val footer = null override val footer = null
override fun initModels() { override fun initModels() {
val asList = preferences.libraryAsList().get() val mode = preferences.libraryViewSetting().get()
grid.checked = !asList grid.checked = mode == 0
list.checked = asList list.checked = mode == 1
comfortableGrid.checked = mode == 2
} }
override fun onItemClicked(item: Item) { override fun onItemClicked(item: Item) {
@ -239,7 +241,13 @@ class LibrarySettingsSheet(
item.group.items.forEach { (it as Item.Radio).checked = false } item.group.items.forEach { (it as Item.Radio).checked = false }
item.checked = true item.checked = true
preferences.libraryAsList().set(item == list) preferences.libraryViewSetting().set(
when (item) {
grid -> 0
list -> 1
else -> 2
}
)
item.group.items.forEach { adapter.notifyItemChanged(it) } item.group.items.forEach { adapter.notifyItemChanged(it) }
} }

View File

@ -5,6 +5,7 @@ import android.animation.AnimatorListenerAdapter
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@ -178,9 +179,11 @@ class MangaAllInOneController :
} }
override fun createPresenter(): MangaAllInOnePresenter { override fun createPresenter(): MangaAllInOnePresenter {
Log.d("Adapter", "Tester8")
return MangaAllInOnePresenter( return MangaAllInOnePresenter(
this, manga!!, source!!, smartSearchConfig this, manga!!, source!!, smartSearchConfig
) )
Log.d("Adapter", "Tester9")
} }
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View { override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
@ -198,6 +201,8 @@ class MangaAllInOneController :
.onEach { fetchMangaFromSource(manualFetch = true) } .onEach { fetchMangaFromSource(manualFetch = true) }
.launchIn(scope) .launchIn(scope)
Log.d("Controller", "Tester1")
// Init RecyclerView and adapter // Init RecyclerView and adapter
adapter = MangaAllInOneAdapter(this, view.context) adapter = MangaAllInOneAdapter(this, view.context)
@ -206,6 +211,7 @@ class MangaAllInOneController :
binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL)) binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
binding.recycler.setHasFixedSize(true) binding.recycler.setHasFixedSize(true)
adapter?.fastScroller = binding.fastScroller adapter?.fastScroller = binding.fastScroller
Log.d("Adapter", "Tester2")
binding.fab.clicks() binding.fab.clicks()
.onEach { .onEach {
@ -233,22 +239,27 @@ class MangaAllInOneController :
binding.actionToolbar.offsetAppbarHeight(activity!!) binding.actionToolbar.offsetAppbarHeight(activity!!)
binding.fab.offsetAppbarHeight(activity!!) binding.fab.offsetAppbarHeight(activity!!)
Log.d("Adapter", "Tester3")
} }
private fun getHeader(): MangaAllInOneHolder? { private fun getHeader(): MangaAllInOneHolder? {
Log.d("Adapter", "Tester4")
return binding.recycler.findViewHolderForAdapterPosition(0) as? MangaAllInOneHolder return binding.recycler.findViewHolderForAdapterPosition(0) as? MangaAllInOneHolder
Log.d("Adapter", "Tester5")
} }
private fun addMangaHeader() { private fun addMangaHeader() {
Log.d("Adapter", "Tester6")
if (adapter?.scrollableHeaders?.isEmpty() == true) { if (adapter?.scrollableHeaders?.isEmpty() == true) {
adapter?.removeAllScrollableHeaders() adapter?.removeAllScrollableHeaders()
adapter?.addScrollableHeader(presenter.headerItem) adapter?.addScrollableHeader(presenter.headerItem)
} }
Log.d("Adapter", "Tester7")
} }
// EXH --> // EXH -->
override fun openSmartSearch() { override fun openSmartSearch() {
val smartSearchConfig = SourceController.SmartSearchConfig(presenter.manga.title, presenter.manga.id!!) val smartSearchConfig = SourceController.SmartSearchConfig(presenter.manga.title, presenter.manga.id)
router?.pushController( router?.pushController(
SourceController( SourceController(
@ -329,12 +340,16 @@ class MangaAllInOneController :
override fun onNextManga(manga: Manga, source: Source, chapters: List<MangaAllInOneChapterItem>, lastUpdateDate: Date, chapterCount: Float) { override fun onNextManga(manga: Manga, source: Source, chapters: List<MangaAllInOneChapterItem>, lastUpdateDate: Date, chapterCount: Float) {
if (manga.initialized) { if (manga.initialized) {
// Update view. // Update view.
Log.d("Controller", "Tester1")
setMangaInfo(manga, source, chapters, lastUpdateDate, chapterCount) setMangaInfo(manga, source, chapters, lastUpdateDate, chapterCount)
Log.d("Controller", "Tester2")
if (fromSource && !presenter.hasRequested && chapters.isNullOrEmpty()) { if (fromSource && !presenter.hasRequested && chapters.isNullOrEmpty()) {
Log.d("Controller", "Tester3")
fetchMangaFromSource(fetchManga = false) fetchMangaFromSource(fetchManga = false)
} }
} else { } else {
// Initialize manga. // Initialize manga.
Log.d("Controller", "Tester4")
fetchMangaFromSource() fetchMangaFromSource()
} }
} }

View File

@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/library_item_selector"
android:padding="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/card"
android:layout_width="wrap_content"
android:layout_height="220dp"
android:layout_gravity="top"
android:background="@drawable/rounded_rectangle"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
tools:ignore="ContentDescription"
android:scaleType="centerCrop"
tools:src="@mipmap/ic_launcher" />
<View
android:id="@+id/gradient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/gradient_shape" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="7dp"
tools:layout_editor_absoluteY="7dp">
<TextView
android:id="@+id/unread_text"
style="@style/TextAppearance.Regular.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:background="@color/colorAccentDark"
android:paddingStart="3dp"
android:paddingTop="1dp"
android:paddingEnd="3dp"
android:paddingBottom="1dp"
android:textColor="@color/md_white_1000"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@+id/download_text"
app:layout_constraintTop_toTopOf="parent"
tools:text="120"
tools:visibility="visible" />
<TextView
android:id="@+id/download_text"
style="@style/TextAppearance.Regular.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:background="@color/md_red_500"
android:paddingStart="3dp"
android:paddingTop="1dp"
android:paddingEnd="3dp"
android:paddingBottom="1dp"
android:textColor="@color/md_white_1000"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@+id/local_text"
app:layout_constraintTop_toTopOf="parent"
tools:text="120"
tools:visibility="visible" />
<TextView
android:id="@+id/local_text"
style="@style/TextAppearance.Regular.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:background="@color/md_teal_500"
android:paddingStart="3dp"
android:paddingTop="1dp"
android:paddingEnd="3dp"
android:paddingBottom="1dp"
android:text="@string/local_source_badge"
android:textColor="@color/md_white_1000"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/title"
style="@style/TextAppearance.Regular.Body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:ellipsize="end"
android:fontFamily="@font/ptsans_narrow_bold"
android:lineSpacingExtra="-4dp"
android:maxLines="2"
android:padding="8dp"
android:shadowColor="@color/textColorPrimaryLight"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="Sample name"
android:orientation="vertical" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@ -15,6 +15,7 @@
<string name="action_search_manually">Search manually</string> <string name="action_search_manually">Search manually</string>
<string name="action_migrate_now">Migrate now</string> <string name="action_migrate_now">Migrate now</string>
<string name="action_copy_now">Copy now</string> <string name="action_copy_now">Copy now</string>
<string name="action_display_comfortable_grid">Comfortable grid</string>
<!-- Preferences --> <!-- Preferences -->
<!-- Filter --> <!-- Filter -->