Fixes to default grid size + older android versions

Spinner in title now only shows if there's multiple categories
Subscreens in migrations now also prompts to stop migration before switching
When hiding categories in single list mode, D&D sorting is renamed to "Category"
Removed top margin from first category header
This commit is contained in:
Jay 2020-02-23 00:03:14 -08:00
parent 55bdd3b4d6
commit bd9633dd08
14 changed files with 119 additions and 42 deletions

View File

@ -19,6 +19,8 @@ interface Category : Serializable {
var mangaSort:Char?
var isFirst:Boolean?
val nameLower: String
get() = name.toLowerCase()
@ -85,9 +87,10 @@ interface Category : Serializable {
LibrarySort.UNREAD -> UNREAD_ASC
LibrarySort.LAST_READ -> LAST_READ_ASC
LibrarySort.TOTAL -> TOTAL_ASC
else -> 'D'
LibrarySort.DRAG_AND_DROP -> DRAG_AND_DROP
else -> DRAG_AND_DROP
}
if (mangaSort != 'D' && !ascending) {
if (mangaSort != DRAG_AND_DROP && !ascending) {
mangaSort?.plus(1)
}
order = -1

View File

@ -14,6 +14,8 @@ class CategoryImpl : Category {
override var mangaSort: Char? = null
override var isFirst: Boolean? = null
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false

View File

@ -52,7 +52,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
*/
fun indexOf(categoryOrder: Int): Int {
return currentItems.indexOfFirst {
if (it is LibraryHeaderItem) it.gCategory().order == categoryOrder
if (it is LibraryHeaderItem) it.category.order == categoryOrder
else false }
}

View File

@ -576,8 +576,9 @@ open class LibraryController(
}
}
R.id.action_migrate -> {
val skipPre = preferences.skipPreMigration().getOrDefault()
router.pushController(
if (preferences.skipPreMigration().getOrDefault()) {
if (skipPre) {
MigrationListController.create(
MigrationProcedureConfig(
selectedMangas.mapNotNull { it.id },null)
@ -586,7 +587,7 @@ open class LibraryController(
else {
PreMigrationController.create( selectedMangas.mapNotNull { it.id } )
}
.withFadeTransaction())
.withFadeTransaction().tag(if (skipPre) MigrationListController.TAG else null))
destroyActionModeIfNeeded()
}
/*R.id.action_to_top, R.id.action_to_bottom -> {

View File

@ -1,12 +1,14 @@
package eu.kanade.tachiyomi.ui.library
import android.graphics.drawable.Drawable
import android.os.Build
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.button.MaterialButton
@ -18,9 +20,11 @@ import eu.davidea.viewholders.FlexibleViewHolder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.visible
import kotlinx.android.synthetic.main.library_category_header_item.view.*
@ -47,13 +51,13 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
holder.bind(categoryF(catId))
}
var category:Category = categoryF(catId)
fun gCategory():Category = categoryF(catId)
val category:Category
get() = categoryF(catId)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other is LibraryHeaderItem) {
return gCategory().id == other.gCategory().id
return category.id == other.category.id
}
return false
}
@ -67,7 +71,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
}
override fun hashCode(): Int {
return -(gCategory().id!!)
return -(category.id!!)
}
class Holder(val view: View, private val adapter: LibraryCategoryAdapter) :
@ -81,16 +85,25 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
init {
updateButton.setOnClickListener { addCategoryToUpdate() }
sortText.setOnClickListener { showCatSortOptions() }
sortText.setOnClickListener { it.post { showCatSortOptions() } }
checkboxImage.setOnClickListener { selectAll() }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
sortText.compoundDrawablesRelative[2]?.mutate()?.setTint(
ContextCompat.getColor(contentView.context, R.color.gray_button))
}
}
fun bind(category: Category) {
sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = (if (category.isFirst == true) 2 else 32).dpToPx
}
sectionText.text = category.name
sortText.text = itemView.context.getString(
when (category.sortingMode()) {
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop
LibrarySort.DRAG_AND_DROP ->
if (category.id == -1) R.string.category
else R.string.action_sort_drag_and_drop
LibrarySort.TOTAL -> R.string.action_sort_total
LibrarySort.UNREAD -> R.string.action_filter_unread
LibrarySort.LAST_READ -> R.string.action_sort_last_read
@ -134,7 +147,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
}
private fun showCatSortOptions() {
val category =
(adapter.getItem(adapterPosition) as? LibraryHeaderItem)?.gCategory() ?: return
(adapter.getItem(adapterPosition) as? LibraryHeaderItem)?.category ?: return
// Create a PopupMenu, giving it the clicked view for an anchor
val popup = PopupMenu(itemView.context, view.category_sort)
@ -162,6 +175,11 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
}
)
if (category.id == -1)
popup.menu.findItem(R.id.action_drag_and_drop).title = contentView.context.getString(
R.string.category
)
if (sortingMode != null && popup.menu is MenuBuilder) {
val m = popup.menu as MenuBuilder
m.setOptionalIconsVisible(true)
@ -193,6 +211,10 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
}
else {
val order = when (menuId) {
R.id.action_drag_and_drop -> {
adapter.libraryListener.sortCategory(category.id!!, 'D' - 'a' + 1)
return
}
R.id.action_total_chaps -> 4
R.id.action_last_read -> 3
R.id.action_unread -> 2

View File

@ -54,7 +54,7 @@ class LibraryItem(val manga: LibraryManga,
val marginParams = card.layoutParams as ConstraintLayout.LayoutParams
marginParams.bottomMargin = 6.dpToPx
card.layoutParams = marginParams
cover_thumbnail.maxHeight = Integer.MAX_VALUE
cover_thumbnail.maxHeight = coverHeight
constraint_layout.minHeight = 0
cover_thumbnail.adjustViewBounds = false
cover_thumbnail.layoutParams = FrameLayout.LayoutParams(

View File

@ -9,6 +9,7 @@ import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Spinner
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView
import androidx.core.content.ContextCompat
@ -72,7 +73,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
override fun contentView():View = recycler_layout
override fun getTitle(): String? {
return null
return when {
spinnerAdapter?.array?.size ?: 0 > 1 -> null
spinnerAdapter?.array?.size == 1 -> return spinnerAdapter?.array?.firstOrNull()
else -> return super.getTitle()
}
}
private var scrollListener = object : RecyclerView.OnScrollListener () {
@ -81,7 +86,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val order = when (val item = adapter.getItem(position)) {
is LibraryHeaderItem -> item.gCategory().order
is LibraryHeaderItem -> item.category.order
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
else -> null
}
@ -92,9 +97,10 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
bottom_sheet.lastCategory = category
bottom_sheet.updateTitle()
if (spinner.selectedItemPosition != order + 1) {
val categortPosition = presenter.categories.indexOf(category)
if (spinner.selectedItemPosition != categortPosition) {
updateScroll = true
spinner.setSelection(order + 1, true)
spinner.setSelection(categortPosition, true)
}
}
}
@ -148,7 +154,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
view.context, tv.resourceId
)
(activity as MainActivity).supportActionBar?.customView = spinner
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true)
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(false)
spinnerAdapter = SpinnerAdapter(
view.context,
R.layout.library_spinner_textview,
@ -161,7 +167,9 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
super.onChangeStarted(handler, type)
if (type.isEnter) {
(activity as MainActivity).supportActionBar?.setDisplayShowCustomEnabled(true)
(activity as MainActivity).supportActionBar
?.setDisplayShowCustomEnabled(router?.backstack?.lastOrNull()?.controller() ==
this && spinnerAdapter?.array?.size ?: 0 > 1)
}
else if (type == ControllerChangeType.PUSH_EXIT) {
(activity as MainActivity).toolbar.menu.findItem(R.id
@ -187,11 +195,19 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
spinner.onItemSelectedListener = null
val categoryNames = presenter.categories.map { it.name }.toTypedArray()
spinnerAdapter = SpinnerAdapter(spinner.context, R.layout.library_spinner_textview,
presenter.categories.map { it.name }.toTypedArray())
if (categoryNames.isNotEmpty()) categoryNames
else arrayOf(spinner.context.getString(R.string.label_library))
)
spinnerAdapter?.setDropDownViewResource(R.layout.library_spinner_entry_text)
spinner.adapter = spinnerAdapter
val isCurrentController = router?.backstack?.lastOrNull()?.controller() ==
this
(activity as AppCompatActivity).supportActionBar
?.setDisplayShowCustomEnabled(isCurrentController && categoryNames.size > 1)
if (isCurrentController) setTitle()
spinner.setSelection(min(presenter.categories.size - 1, activeCategory + 1))
updateScroll = false
@ -202,10 +218,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
} else if (justStarted) {
val position = if (freshStart) adapter.indexOf(activeCategory) else null
if (position != null)
(recycler.layoutManager as LinearLayoutManager)
.scrollToPositionWithOffset(position, (-30).dpToPx)
if (freshStart) scrollToHeader(activeCategory)
}
else {
updateScroll = true
@ -213,21 +226,25 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
adapter.isLongPressDragEnabled = canDrag()
tabsVisibilityRelay.call(false)
bottom_sheet.lastCategory = presenter.categories[MathUtils.clamp(
bottom_sheet.lastCategory = presenter.categories.getOrNull(MathUtils.clamp(
activeCategory, 0, presenter.categories.size - 1
)]
))
bottom_sheet.updateTitle()
spinner.onItemSelectedListener = IgnoreFirstSpinnerListener { pos ->
if (updateScroll) {
updateScroll = false
return@IgnoreFirstSpinnerListener
}
val headerPosition = adapter.indexOf(pos - 1)
if (headerPosition > -1) {
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
headerPosition, (-30).dpToPx
)
}
scrollToHeader(pos - 1)
}
}
private fun scrollToHeader(pos: Int) {
val headerPosition = adapter.indexOf(pos)
if (headerPosition > -1) {
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
headerPosition, if (headerPosition == 0) 0 else (-30).dpToPx
)
}
}

View File

@ -345,8 +345,13 @@ class LibraryPresenter(
}
}
fun getCategory(categoryId: Int): Category {
return categories.find { it.id == categoryId } ?: createDefaultCategory()
private fun getCategory(categoryId: Int): Category {
val category = categories.find { it.id == categoryId } ?: createDefaultCategory()
if (category.isFirst == null) {
category.isFirst = (category.id ?: 0 <= 0 ||
(category.order == 0 && categories.none { it.id == 0 }))
}
return category
}
private fun sortCategory(i1: LibraryItem, i2: LibraryItem,

View File

@ -26,10 +26,12 @@ import eu.kanade.tachiyomi.ui.base.controller.RxController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.requestPermissionsSafe
import eu.kanade.tachiyomi.ui.catalogue.CatalogueController
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
import eu.kanade.tachiyomi.ui.main.SearchActivity
import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersController
import eu.kanade.tachiyomi.ui.manga.info.MangaInfoController
import eu.kanade.tachiyomi.ui.manga.track.TrackController
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
import eu.kanade.tachiyomi.util.system.toast
import kotlinx.android.synthetic.main.main_activity.*
@ -40,7 +42,7 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
class MangaController : RxController, TabbedController {
class MangaController : RxController, TabbedController, BottomNavBarInterface {
constructor(manga: Manga?,
fromCatalogue: Boolean = false,
@ -216,6 +218,13 @@ class MangaController : RxController, TabbedController {
//tab.icon = drawable
}
override fun canChangeTabs(block: () -> Unit): Boolean {
val migrationListController = router.getControllerWithTag(MigrationListController.TAG)
as? BottomNavBarInterface
if (migrationListController != null) return migrationListController.canChangeTabs(block)
return true
}
private inner class MangaDetailAdapter : RouterPagerAdapter(this@MangaController) {
private val tabCount = if (Injekt.get<TrackManager>().hasLoggedServices()) 3 else 2

View File

@ -18,12 +18,13 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchPresenter
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
import uy.kohesive.injekt.injectLazy
class SearchController(
private var manga: Manga? = null
) : CatalogueSearchController(manga?.originalTitle()) {
) : CatalogueSearchController(manga?.originalTitle()), BottomNavBarInterface{
private var newManga: Manga? = null
private var progress = 1
@ -191,5 +192,10 @@ class SearchController(
}
}
override fun canChangeTabs(block: () -> Unit): Boolean {
val migrationListController = router.getControllerWithTag(MigrationListController.TAG)
as? BottomNavBarInterface
if (migrationListController != null) return migrationListController.canChangeTabs(block)
return true
}
}

View File

@ -17,13 +17,12 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.marginBottom
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationProcedureConfig
import kotlinx.android.synthetic.main.pre_migration_controller.fab
import kotlinx.android.synthetic.main.pre_migration_controller.recycler
import kotlinx.android.synthetic.main.pre_migration_controller.*
import uy.kohesive.injekt.injectLazy
class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), FlexibleAdapter
@ -98,7 +97,7 @@ class PreMigrationController(bundle: Bundle? = null) : BaseController(bundle), F
config.toList(),
extraSearchParams = extraParam
)
).withFadeTransaction())
).withFadeTransaction().tag(MigrationListController.TAG))
}
override fun onSaveInstanceState(outState: Bundle) {

View File

@ -446,6 +446,7 @@ class MigrationListController(bundle: Bundle? = null) : BaseController(bundle),
companion object {
const val CONFIG_EXTRA = "config_extra"
const val TAG = "migration_list"
fun create(config: MigrationProcedureConfig): MigrationListController {
return MigrationListController(Bundle().apply {

View File

@ -21,7 +21,10 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
}
val itemWidth: Int
get() = measuredWidth / manager.spanCount
get() {
return if (spanCount == 0) measuredWidth / getTempSpan()
else measuredWidth / manager.spanCount
}
init {
if (attrs != null) {
@ -34,6 +37,13 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
layoutManager = manager
}
private fun getTempSpan():Int {
if (spanCount == 0 && columnWidth > 0) {
return max(1, measuredWidth / columnWidth)
}
return 2
}
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
super.onMeasure(widthSpec, heightSpec)
if (spanCount == 0 && columnWidth > 0) {

View File

@ -443,6 +443,8 @@
</plurals>
<string name="remember_choice">Remember this choice</string>
<string name="already_in_category">Manga already in category</string>
<string name="category">Category</string>
<!-- Catalogue fragment -->
<string name="source_search_options">Search filters</string>