Library display options moved

Moved all the display options into a new sheet
Fixes to bottom sheet when switching orientations
Swipe left or right in single list mode to jump to categories
Setting a default sort for categories, based on preference
Uniform gird option for confortable and compact grid, default true)
This commit is contained in:
Jay 2020-02-29 01:22:54 -08:00
parent 5454b74685
commit e842db3bca
35 changed files with 603 additions and 1258 deletions

View File

@ -57,6 +57,17 @@ interface Category : Serializable {
else -> null
}
fun changeSortTo(sort: Int) {
mangaSort = when (sort) {
LibrarySort.ALPHA -> ALPHA_ASC
LibrarySort.LAST_UPDATED -> UPDATED_ASC
LibrarySort.UNREAD -> UNREAD_ASC
LibrarySort.LAST_READ -> LAST_READ_ASC
LibrarySort.TOTAL -> ALPHA_ASC
else -> ALPHA_ASC
}
}
companion object {
private const val DRAG_AND_DROP = 'D'
private const val ALPHA_ASC = 'a'

View File

@ -113,6 +113,10 @@ object PreferenceKeys {
const val libraryLayout = "pref_display_library_layout"
const val gridSize = "grid_size"
const val uniformGrid = "uniform_grid"
const val libraryAsSingleList = "library_as_single_list"
const val lang = "app_language"

View File

@ -173,6 +173,10 @@ class PreferencesHelper(val context: Context) {
fun libraryLayout() = rxPrefs.getInteger(Keys.libraryLayout, 1)
fun gridSize() = rxPrefs.getInteger(Keys.gridSize, 1)
fun uniformGrid() = rxPrefs.getBoolean(Keys.uniformGrid, true)
fun libraryAsSingleList() = rxPrefs.getBoolean(Keys.libraryAsSingleList, false)
fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false)
@ -239,7 +243,7 @@ class PreferencesHelper(val context: Context) {
fun lastExtCheck() = rxPrefs.getLong("last_ext_check", 0)
fun unreadBadgeType() = rxPrefs.getInteger("unread_badge_type", 1)
fun unreadBadgeType() = rxPrefs.getInteger("unread_badge_type", 2)
fun keepCatSort() = rxPrefs.getInteger(Keys.keepCatSort, 0)

View File

@ -0,0 +1,128 @@
package eu.kanade.tachiyomi.ui.library
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.RadioButton
import android.widget.RadioGroup
import com.f2prateek.rx.preferences.Preference
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.setBottomEdge
import eu.kanade.tachiyomi.util.view.setEdgeToEdge
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.display_bottom_sheet.*
import uy.kohesive.injekt.injectLazy
class DisplayBottomSheet(private val controller: LibraryController) : BottomSheetDialog
(controller.activity!!, R.style.BottomSheetDialogTheme) {
val activity = controller.activity!!
/**
* Preferences helper.
*/
private val preferences by injectLazy<PreferencesHelper>()
private var sheetBehavior: BottomSheetBehavior<*>
init {
// Use activity theme for this layout
val view = activity.layoutInflater.inflate(R.layout.display_bottom_sheet, null)
setContentView(view)
sheetBehavior = BottomSheetBehavior.from(view.parent as ViewGroup)
setEdgeToEdge(activity, bottom_sheet, view, false)
val height = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.window.decorView.rootWindowInsets.systemWindowInsetBottom
} else 0
sheetBehavior.peekHeight = 220.dpToPx + height
sheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) { }
override fun onStateChanged(p0: View, state: Int) {
if (state == BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior.skipCollapsed = true
}
}
})
}
override fun onStart() {
super.onStart()
sheetBehavior.skipCollapsed = true
sheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
}
/**
* Called when the sheet is created. It initializes the listeners and values of the preferences.
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initGeneralPreferences()
setBottomEdge(unread_badge_group, activity)
close_button.setOnClickListener {
dismiss()
true
}
settings_scroll_view.viewTreeObserver.addOnGlobalLayoutListener {
val isScrollable =
settings_scroll_view!!.height < bottom_sheet.height +
settings_scroll_view.paddingTop + settings_scroll_view.paddingBottom
close_button.visibleIf(isScrollable)
}
}
private fun initGeneralPreferences() {
display_group.bindToPreference(preferences.libraryLayout()) {
controller.reattachAdapter()
if (sheetBehavior.state == BottomSheetBehavior.STATE_COLLAPSED)
dismiss()
}
uniform_grid.bindToPreference(preferences.uniformGrid()) {
controller.reattachAdapter()
}
grid_size_toggle_group.bindToPreference(preferences.gridSize()) {
controller.reattachAdapter()
}
download_badge.bindToPreference(preferences.downloadBadge()) {
controller.presenter.requestDownloadBadgesUpdate()
}
unread_badge_group.bindToPreference(preferences.unreadBadgeType()) {
controller.presenter.requestUnreadBadgesUpdate()
}
}
/**
* Binds a checkbox or switch view with a boolean preference.
*/
private fun CompoundButton.bindToPreference(pref: Preference<Boolean>, block: () -> Unit) {
isChecked = pref.getOrDefault()
setOnCheckedChangeListener { _, isChecked ->
pref.set(isChecked)
block()
}
}
/**
* Binds a radio group with a int preference.
*/
private fun RadioGroup.bindToPreference(pref: Preference<Int>, block: () -> Unit) {
(getChildAt(pref.getOrDefault()) as RadioButton).isChecked = true
setOnCheckedChangeListener { _, checkedId ->
val index = indexOfChild(findViewById(checkedId))
pref.set(index)
block()
}
}
}

View File

@ -230,8 +230,6 @@ open class LibraryController(
override fun onPageSelected(position: Int) {
preferences.lastUsedCategory().set(position)
activeCategory = position
bottom_sheet.lastCategory = pagerAdapter?.categories?.getOrNull(position)
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP) bottom_sheet.updateTitle()
}
override fun onPageScrolled(
@ -293,7 +291,7 @@ open class LibraryController(
fab.animate().scaleX(scale).scaleY(scale).setDuration(200).start()
fab.isClickable = downloading
fab.isFocusable = downloading
bottom_sheet?.adjustTitleMargin(downloading)
bottom_sheet?.adjustFiltersMargin(downloading)
}
}
@ -362,9 +360,6 @@ open class LibraryController(
// Restore active category.
library_pager.setCurrentItem(activeCat, false)
bottom_sheet.lastCategory = adapter.categories.getOrNull(activeCat)
bottom_sheet.updateTitle()
tabsVisibilityRelay.call(categories.size > 1)
libraryMangaRelay.call(LibraryMangaEvent(mangaMap))
@ -430,7 +425,7 @@ open class LibraryController(
/**
* Reattaches the adapter to the view pager to recreate fragments
*/
protected open fun reattachAdapter() {
open fun reattachAdapter() {
val adapter = pagerAdapter ?: return
val position = library_pager.currentItem
@ -518,10 +513,14 @@ open class LibraryController(
if (bottom_sheet.sheetBehavior?.isHideable == true &&
bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED)
else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED
&& bottom_sheet.sheetBehavior?.skipCollapsed == false)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
}
R.id.action_library_display -> {
DisplayBottomSheet(this).show()
}
else -> return super.onOptionsItemSelected(item)
}
@ -530,7 +529,10 @@ open class LibraryController(
fun showFiltersBottomSheet() {
if (bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_HIDDEN)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
bottom_sheet.sheetBehavior?.state =
if (bottom_sheet.sheetBehavior?.skipCollapsed == false)
BottomSheetBehavior.STATE_COLLAPSED
else BottomSheetBehavior.STATE_EXPANDED
}

View File

@ -24,12 +24,13 @@ class LibraryGridHolder(
private val view: View,
adapter: LibraryCategoryAdapter,
var width:Int,
compact: Boolean,
private var fixedSize: Boolean
) : LibraryHolder(view, adapter) {
init {
play_layout.setOnClickListener { playButtonClicked() }
if (fixedSize) {
if (compact) {
text_layout.gone()
}
else {
@ -58,7 +59,7 @@ class LibraryGridHolder(
compact_title.text = title.text
setUnreadBadge(badge_view, item)
play_layout.visibility = if (item.manga.unread > 0 && item.unreadType > -1)
play_layout.visibility = if (item.manga.unread > 0 && item.unreadType > 0)
View.VISIBLE else View.GONE
// Update the cover.

View File

@ -78,20 +78,15 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
private val sortText: TextView = view.findViewById(R.id.category_sort)
private val updateButton: ImageView = view.findViewById(R.id.update_button)
private val checkboxImage: ImageView = view.findViewById(R.id.checkbox)
private val dropDown:Drawable?
init {
updateButton.setOnClickListener { addCategoryToUpdate() }
sortText.setOnClickListener { it.post { showCatSortOptions() } }
checkboxImage.setOnClickListener { selectAll() }
sectionText.setOnClickListener { it.post {
adapter.libraryListener.showCategories(adapterPosition, it)
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
sortText.compoundDrawablesRelative[2]?.mutate()?.setTint(
ContextCompat.getColor(contentView.context, R.color.gray_button))
}
dropDown = sectionText.compoundDrawablesRelative[2]
updateButton.drawable.mutate()
}
@ -99,10 +94,6 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = (if (category.isFirst == true) 2 else 32).dpToPx
}
if (category.isFirst == true && category.isLast == true)
sectionText.setCompoundDrawablesRelative(null, null, null, null)
else
sectionText.setCompoundDrawablesRelative(null, null, dropDown, null)
sectionText.text = category.name
sortText.text = itemView.context.getString(R.string.sort_by_,

View File

@ -29,8 +29,8 @@ abstract class LibraryHolder(
badge.setUnreadDownload(
when {
item.chapterCount > -1 -> item.chapterCount
item.unreadType == 1 -> item.manga.unread
item.unreadType == 0 -> if (item.manga.unread > 0) -1 else -2
item.unreadType == 2 -> item.manga.unread
item.unreadType == 1 -> if (item.manga.unread > 0) -1 else -2
else -> -2
},
when {

View File

@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.library
import android.annotation.SuppressLint
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
@ -17,17 +18,19 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.android.synthetic.main.catalogue_grid_item.view.*
import uy.kohesive.injekt.injectLazy
class LibraryItem(val manga: LibraryManga,
private val libraryLayout: Preference<Int>,
private val fixedSize: Preference<Boolean>,
header: LibraryHeaderItem?) :
AbstractSectionableItem<LibraryHolder, LibraryHeaderItem?>(header), IFilterable<String> {
var downloadCount = -1
var unreadType = 1
var unreadType = 2
var chapterCount = -1
override fun getLayoutRes(): Int {
@ -41,6 +44,7 @@ class LibraryItem(val manga: LibraryManga,
val parent = adapter.recyclerView
return if (parent is AutofitRecyclerView) {
val libraryLayout = libraryLayout.getOrDefault()
val isFixedSize = fixedSize.getOrDefault()
if (libraryLayout == 0) {
LibraryListHolder(view, adapter as LibraryCategoryAdapter)
}
@ -48,33 +52,42 @@ class LibraryItem(val manga: LibraryManga,
view.apply {
val coverHeight = (parent.itemWidth / 3f * 4f).toInt()
if (libraryLayout == 1) {
gradient.layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
(coverHeight * 0.66f).toInt(),
Gravity.BOTTOM)
card.updateLayoutParams<ConstraintLayout.LayoutParams> {
bottomMargin = 6.dpToPx
}
}
else if (libraryLayout == 2) {
constraint_layout.background = ContextCompat.getDrawable(
context, R.drawable.library_item_selector
)
}
if (isFixedSize) {
constraint_layout.layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
)
val marginParams = card.layoutParams as ConstraintLayout.LayoutParams
marginParams.bottomMargin = 6.dpToPx
card.layoutParams = marginParams
cover_thumbnail.maxHeight = coverHeight
cover_thumbnail.maxHeight = (parent.itemWidth / 3f * 3.7f).toInt()
constraint_layout.minHeight = 0
cover_thumbnail.adjustViewBounds = false
cover_thumbnail.layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
coverHeight
(parent.itemWidth / 3f * 3.7f).toInt()
)
} else if (libraryLayout == 2) {
} else {
constraint_layout.minHeight = coverHeight
cover_thumbnail.minimumHeight = (parent.itemWidth / 3f * 3.6f).toInt()
cover_thumbnail.maxHeight = (parent.itemWidth / 3f * 6f).toInt()
constraint_layout.background = ContextCompat.getDrawable(
context, R.drawable.library_item_selector
)
}
}
LibraryGridHolder(
view,
adapter as LibraryCategoryAdapter,
parent.itemWidth,
libraryLayout == 1
libraryLayout == 1,
isFixedSize
)
}
} else {

View File

@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.ui.library
import android.graphics.Rect
import android.os.Bundle
import android.util.TypedValue
import android.view.Gravity
@ -13,7 +14,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView
import androidx.core.math.MathUtils
import androidx.core.math.MathUtils.clamp
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@ -32,6 +32,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.main.SwipeGestureInterface
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.inflate
@ -40,6 +41,7 @@ import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.android.synthetic.main.filter_bottom_sheet.*
import kotlinx.android.synthetic.main.library_grid_recycler.*
import kotlinx.android.synthetic.main.library_list_controller.*
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.android.synthetic.main.spinner_title.view.*
@ -51,12 +53,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
FlexibleAdapter.OnItemClickListener,
FlexibleAdapter.OnItemLongClickListener,
FlexibleAdapter.OnItemMoveListener,
LibraryCategoryAdapter.LibraryListener{
LibraryCategoryAdapter.LibraryListener,
SwipeGestureInterface {
private lateinit var adapter: LibraryCategoryAdapter
// private lateinit var spinner: AutoCompleteTextView
private var lastClickPosition = -1
private var updateScroll = true
@ -65,16 +66,16 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
private var lastItemPosition:Int? = null
private var lastItem:IFlexible<*>? = null
private var lastHeaderPos = 0
private lateinit var customTitleSpinner: LinearLayout
private lateinit var titlePopupMenu:PopupMenu
var switchingCategories = false
/**
* Recycler view of the list of manga.
*/
private lateinit var recycler: RecyclerView
// private lateinit var recycler: RecyclerView
override fun contentView():View = recycler
override fun contentView():View = recycler_layout
override fun getTitle(): String? {
return when {
@ -99,8 +100,6 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
activeCategory = order
val category = presenter.categories.find { it.order == order }
bottom_sheet.lastCategory = category
bottom_sheet.updateTitle()
//val categortPosition = presenter.categories.indexOf(category)
customTitleSpinner.category_title.text = category?.name ?: ""
/*if (spinner.selectedItemPosition != categortPosition) {
@ -127,7 +126,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
override fun layoutView(view: View) {
adapter = LibraryCategoryAdapter(this)
recycler =
/* recycler =
(library_layout.inflate(R.layout.library_grid_recycler) as AutofitRecyclerView).apply {
spanCount = if (libraryLayout == 0) 1 else mangaPerRow
manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
@ -137,11 +136,21 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
return if (item is LibraryHeaderItem) manager.spanCount else 1
}
})
}
}*/
//recycler.spanCount = if (libraryLayout == 0) 1 else mangaPerRow
if (libraryLayout == 0)recycler.spanCount = 1
else recycler.columnWidth = (90 + (preferences.gridSize().getOrDefault() * 30)).dpToPx
recycler.manager.spanSizeLookup = (object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (libraryLayout == 0) return 1
val item = this@LibraryListController.adapter.getItem(position)
return if (item is LibraryHeaderItem) recycler.manager.spanCount else 1
}
})
recycler.setHasFixedSize(true)
recycler.adapter = adapter
library_layout.addView(recycler, 0)
//recycler_layout.addView(recycler)
adapter.fastScroller = fast_scroller
recycler.addOnScrollListener(scrollListener)
@ -245,10 +254,6 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
adapter.isLongPressDragEnabled = canDrag()
tabsVisibilityRelay.call(false)
bottom_sheet.lastCategory = presenter.categories.getOrNull(MathUtils.clamp(
activeCategory, 0, presenter.categories.size - 1
))
bottom_sheet.updateTitle()
titlePopupMenu.menu.clear()
presenter.categories.forEach { category ->
titlePopupMenu.menu.add(0, category.order, max(0, category.order), category.name)
@ -266,26 +271,25 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
}*/
}
private fun scrollToHeader(pos: Int, offset: Float? = null) {
private fun scrollToHeader(pos: Int, fade:Boolean = false) {
val headerPosition = adapter.indexOf(pos)
switchingCategories = true
if (headerPosition > -1) {
recycler.suppressLayout(true)
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
headerPosition, offset?.toInt() ?: if (headerPosition == 0) 0 else (-30).dpToPx
headerPosition, if (headerPosition == 0) 0 else (-30).dpToPx
)
lastHeaderPos = pos
if (offset != null && preferences.libraryLayout().getOrDefault() == 2) {
launchUI {
delay(100)
if (pos == lastHeaderPos)
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
headerPosition, offset.toInt()
)
}
}
recycler.suppressLayout(false)
}
launchUI {
delay(100)
switchingCategories = false
}
}
override fun reattachAdapter() {
if (libraryLayout == 0)recycler.spanCount = 1
else recycler.columnWidth = (90 + (preferences.gridSize().getOrDefault() * 30)).dpToPx
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
libraryLayout = preferences.libraryLayout().getOrDefault()
@ -395,6 +399,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
* @return true if the item should be selected, false otherwise.
*/
override fun onItemClick(view: View?, position: Int): Boolean {
if (switchingCategories) return false
val item = adapter.getItem(position) as? LibraryItem ?: return false
return if (adapter.mode == SelectableAdapter.Mode.MULTI) {
lastClickPosition = position
@ -577,4 +582,33 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
}
popupMenu.show()
}
override fun onSwipeBottom(x: Float, y: Float) { }
override fun onSwipeTop(x: Float, y: Float) { }
override fun onSwipeLeft(x: Float, y: Float) = goToNextCategory(x, y,-1)
override fun onSwipeRight(x: Float, y: Float) = goToNextCategory(x, y,1)
private fun goToNextCategory(x: Float, y: Float, offset: Int) {
val editTextRect = Rect()
bottom_sheet.getGlobalVisibleRect(editTextRect)
if (editTextRect.contains(x.toInt(), y.toInt())) {
return
}
val position =
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val order = when (val item = adapter.getItem(position)) {
is LibraryHeaderItem -> item.category.order
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
?.plus(if (offset < 0) 1 else 0)
else -> null
}
if (order != null) {
var newOffset = order + offset
while (adapter.indexOf(newOffset) == -1 && presenter.categories.any { it.order == newOffset }) {
newOffset += offset
}
scrollToHeader (newOffset, true)
}
}
}

View File

@ -41,7 +41,7 @@ class LibraryListHolder(
subtitle.visibility = if (!item.manga.originalAuthor().isNullOrBlank()) View.VISIBLE
else View.GONE
play_layout.visibility = if (item.manga.unread > 0 && item.unreadType > -1)
play_layout.visibility = if (item.manga.unread > 0 && item.unreadType > 0)
View.VISIBLE else View.GONE
play_layout.setOnClickListener { playButtonClicked() }

View File

@ -353,13 +353,16 @@ class LibraryPresenter(
}
private fun sortCategory(i1: LibraryItem, i2: LibraryItem,
lastReadManga: Map<Long, Int>,
initCat: Category? = null):
Int {
return if (initCat != null || i1.manga.category == i2.manga.category) {
val category = initCat ?: allCategories.find { it.id == i1.manga.category }
lastReadManga: Map<Long, Int>, initCat: Category? = null
): Int {
return if (initCat != null || i1.manga.category == i2.manga.category) {
val category = initCat ?: allCategories.find { it.id == i1.manga.category } ?: return 0
if (category.mangaOrder.isNullOrEmpty() && category.mangaSort == null) {
category.changeSortTo(preferences.librarySortingMode().getOrDefault())
db.insertCategory(category).asRxObservable().subscribe()
}
val compare = when {
category?.mangaSort != null -> {
category.mangaSort != null -> {
var sort = when (category.sortingMode()) {
LibrarySort.ALPHA -> sortAlphabetical(i1, i2)
LibrarySort.LAST_UPDATED -> i2.manga.last_update.compareTo(i1.manga.last_update)
@ -384,8 +387,7 @@ class LibraryPresenter(
}
else -> sortAlphabetical(i1, i2)
}
if (!category.isAscending())
sort *= -1
if (!category.isAscending()) sort *= -1
sort
}
category?.mangaOrder?.isEmpty() == false -> {
@ -401,13 +403,11 @@ class LibraryPresenter(
}
else -> 0
}
if (compare == 0) {
if (category?.isAscending() != false) sortAlphabetical(i1, i2)
else sortAlphabetical(i2, i1)
}
else compare
}
else {
if (compare == 0) {
if (category?.isAscending() != false) sortAlphabetical(i1, i2)
else sortAlphabetical(i2, i1)
} else compare
} else {
val category = allCategories.find { it.id == i1.manga.category }?.order ?: -1
val category2 = allCategories.find { it.id == i2.manga.category }?.order ?: -1
category.compareTo(category2)
@ -446,7 +446,8 @@ class LibraryPresenter(
val libraryMap =
if (!preferences.libraryAsSingleList().getOrDefault()) {
libraryManga.map { manga ->
LibraryItem(manga, libraryLayout, null).apply { unreadType = unreadBadgeType }
LibraryItem(manga, libraryLayout, preferences.uniformGrid(),null).apply { unreadType =
unreadBadgeType }
}.groupBy {
if (showCategories) it.manga.category else -1
}
@ -461,7 +462,7 @@ class LibraryPresenter(
(LibraryHeaderItem({ getCategory(it) }, entry.key))
entry.value.map {
LibraryItem(
it, libraryLayout, categoryItem
it, libraryLayout, preferences.uniformGrid(), categoryItem
).apply { unreadType = unreadBadgeType }
}
}.map {

View File

@ -2,38 +2,24 @@ package eu.kanade.tachiyomi.ui.library.filter
import android.content.Context
import android.content.res.Configuration
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Spinner
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.ContextCompat
import com.f2prateek.rx.preferences.Preference
import com.google.android.material.bottomsheet.BottomSheetBehavior
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.ui.library.LibrarySort
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.inflate
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePadding
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.android.synthetic.main.filter_bottom_sheet.view.*
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
@ -64,18 +50,12 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
private lateinit var tracked: FilterTagGroup
private lateinit var categories: FilterTagGroup
// private lateinit var categories: FilterTagGroup
private var mangaType: FilterTagGroup? = null
var lastCategory:Category? = null
var sheetBehavior:BottomSheetBehavior<View>? = null
var peekHeight = 0
var startingTitle = ""
private lateinit var clearButton:ImageView
private val filterItems:MutableList<FilterTagGroup> by lazy {
@ -83,8 +63,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
list.add(downloaded)
list.add(unread)
list.add(completed)
if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
list.add(categories)
//if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
// list.add(categories)
if (Injekt.get<TrackManager>().hasLoggedServices())
list.add(tracked)
list
@ -94,22 +74,12 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
var pager:View? = null
fun onCreate(pagerView:View) {
if (isLandscape() || isTablet()) {
side_layout.orientation = HORIZONTAL
sorting_layout.updateLayoutParams<MarginLayoutParams> {
bottomMargin = 0
topMargin = 0
}
sortScrollView?.updatePadding(
bottom = 10.dpToPx,
top = 0
)
}
clearButton = clear_button
filter_layout.removeView(clearButton)
sheetBehavior = BottomSheetBehavior.from(this)
val phoneLandscape = (isLandscape() && !isTablet())
sheetBehavior?.isHideable = !phoneLandscape
sheetBehavior?.isHideable = true
sheetBehavior?.skipCollapsed = phoneLandscape
top_bar.setOnClickListener {
if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
@ -117,15 +87,12 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
}
}
title.text = startingTitle
pager = pagerView
updateTitle()
val shadow2:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2)
val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow)
val snackbarLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout)
if (phoneLandscape) {
shadow.alpha = 0f
sheetBehavior?.peekHeight = 0
sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
}
sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) {
@ -149,9 +116,9 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
shadow.alpha = 1f
pager?.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0)
snackbarLayout.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0)
preferences.hideFiltersAtStart().set(false)
if (!phoneLandscape)
preferences.hideFiltersAtStart().set(false)
}
else setMainSortText()
if (state == BottomSheetBehavior.STATE_EXPANDED) {
top_bar.alpha = 0f
if (phoneLandscape)
@ -162,7 +129,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
shadow.alpha = 0f
pager?.updatePaddingRelative(bottom = 0)
snackbarLayout.updatePaddingRelative(bottom = 0)
preferences.hideFiltersAtStart().set(true)
if (!phoneLandscape)
preferences.hideFiltersAtStart().set(true)
}
//top_bar.isClickable = state == BottomSheetBehavior.STATE_COLLAPSED
//top_bar.isFocusable = state == BottomSheetBehavior.STATE_COLLAPSED
@ -179,76 +147,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
if (phoneLandscape && shadow2.visibility != View.GONE) {
shadow2.gone()
}
/*top_bar.viewTreeObserver.addOnGlobalLayoutListener {
/*val peekingHeight = if (phoneLandscape) 0
else if (!title.text.isNullOrBlank()) top_bar.height
else if (peekHeight != 0) -1
else 0
if (peekingHeight > -1 && (peekHeight == 0 || peekingHeight > 0)) {
sheetBehavior?.peekHeight = peekingHeight
peekHeight = peekingHeight
}*/
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
fastScroller?.updateLayoutParams<CoordinatorLayout.LayoutParams> {
bottomMargin = if (phoneLandscape) 0 else (top_bar.height - height)
}
pager?.updatePaddingRelative(bottom = if (phoneLandscape) 0 else
(top_bar.height - height))
coordLayout.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0)
}
else {
updateRootPadding()
}
}*/
createTags()
sorting_layout.visibility =
if (preferences.libraryAsSingleList().getOrDefault()) View.GONE
else View.VISIBLE
library_sort_text.setOnClickListener { showMainSortOptions() }
category_sort_text.setOnClickListener { showCatSortOptions() }
clearButton.setOnClickListener { clearFilters() }
download_checkbox.isChecked = preferences.downloadBadge().getOrDefault()
download_checkbox.setOnCheckedChangeListener { _, isChecked ->
preferences.downloadBadge().set(isChecked)
onGroupClicked(ACTION_DOWNLOAD_BADGE)
}
setUnreadIcon()
unread_badge.setOnClickListener {
showUnreadMenu()
}
display_spinner.bindToPreference(preferences.libraryLayout())
}
override fun onSaveInstanceState(): Parcelable? {
val bundle = Bundle()
bundle.putParcelable("superState", super.onSaveInstanceState())
bundle.putInt("peek", sheetBehavior?.peekHeight ?: 0)
bundle.putString("title", title.text.toString())
return bundle
}
override fun onRestoreInstanceState(state: Parcelable?) {
if (state is Bundle) // implicit null check
{
/*this.peekHeight = state.getInt("peek")
this.startingTitle = state.getString("title") ?: ""
val sheet = BottomSheetBehavior.from(this)
if (isLandscape() && !isTablet())
sheet.peekHeight = 0
else
sheet.peekHeight = peekHeight
title.text = startingTitle
super.onRestoreInstanceState( state.getParcelable("superState"))
top_bar.alpha =
if (sheet.state == BottomSheetBehavior.STATE_COLLAPSED) 1f
else 0f
*/
super.onRestoreInstanceState(state.getParcelable("superState"))
}
else super.onRestoreInstanceState(state)
}
private fun isLandscape(): Boolean {
@ -260,50 +160,6 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
}
fun updateTitle() {
launchUI {
val text = withContext(Dispatchers.IO) {
val filters = getFilters().toMutableList()
if (filters.isEmpty()) {
context.getString(
R.string.sorting_by_, context.getString(
when (sorting()) {
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.DRAG_AND_DROP -> 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
else -> R.string.title
}
)
)
} else {
filters.add(
0, when (sorting()) {
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.DRAG_AND_DROP -> 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
else -> R.string.title
}
)
filters.joinToString(", ") { context.getString(it) }
}
}
title.text = text
setMainSortText()
}
}
fun adjustTitleMargin(downloading: Boolean) {
val params = title.layoutParams as? MarginLayoutParams ?: return
params.rightMargin = (if (downloading) 80 else 8).dpToPx
title.layoutParams = params
filter_scroll.updatePaddingRelative(end = (if (downloading) 80 else 20).dpToPx)
}
fun updateRootPadding(progress: Float? = null) {
val minHeight = sheetBehavior?.peekHeight ?: 0
val maxHeight = height
@ -318,62 +174,19 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
pager?.updatePaddingRelative(bottom = (minHeight * (1 + trueProgress)).toInt())
}
fun sorting(trueSort:Boolean = false): Int {
val sortingMode = preferences.librarySortingMode().getOrDefault()
val singleList = preferences.libraryAsSingleList().getOrDefault()
return if (!trueSort &&
(sortingMode == LibrarySort.DRAG_AND_DROP || singleList) &&
lastCategory != null &&
!preferences.hideCategories().getOrDefault()) {
lastCategory?.sortingMode() ?: LibrarySort.DRAG_AND_DROP
}
else {
sortingMode
}
}
fun hasActiveFilters() = filterItems.any { it.isActivated }
private fun getFilters(): List<Int> {
val filters = mutableListOf<Int>()
val categoriesOn = !preferences.hideCategories().getOrDefault()
if (!categoriesOn) {
filters.add(R.string.hiding_categories)
}
var filter = preferences.filterDownloaded().getOrDefault()
if (filter > 0) {
filters.add(if (filter == 1) R.string.action_filter_downloaded else R.string
.action_filter_not_downloaded)
}
filter = preferences.filterUnread().getOrDefault()
if (filter > 0) {
filters.add(when (filter) {
3 -> R.string.action_filter_read
2 -> R.string.action_filter_in_progress
else -> R.string.action_filter_not_started
})
}
filter = preferences.filterCompleted().getOrDefault()
if (filter > 0) {
filters.add(if (filter == 1) R.string.completed else R.string
.ongoing)
}
filter = preferences.filterTracked().getOrDefault()
if (filter > 0) {
filters.add(if (filter == 1) R.string.action_filter_tracked else R.string
.action_filter_not_tracked)
}
filter = preferences.filterMangaType().getOrDefault()
if (filter > 0) {
filters.add(R.string.manhwa_only)
}
return filters
}
private fun createTags() {
categories = inflate(R.layout.filter_buttons) as FilterTagGroup
categories.setup(this, R.string.action_hide_categories)
//categories = inflate(R.layout.filter_buttons) as FilterTagGroup
// categories.setup(this, R.string.action_hide_categories)
// list.add(categories)
hide_categories.isChecked = preferences.hideCategories().getOrDefault()
hide_categories.setOnCheckedChangeListener { _, isChecked ->
preferences.hideCategories().set(isChecked)
onGroupClicked(ACTION_REFRESH)
}
downloaded = inflate(R.layout.filter_buttons) as FilterTagGroup
downloaded.setup(this, R.string.action_filter_downloaded, R.string.action_filter_not_downloaded)
@ -396,6 +209,10 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
private fun checkForManhwa() {
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
val db:DatabaseHelper by injectLazy()
val showCategoriesCheckBox = withContext(Dispatchers.IO) {
db.getCategories().executeAsBlocking()
.isNotEmpty()
}
val librryManga = db.getLibraryMangas().executeAsBlocking()
if (librryManga.any { it.mangaType() == Manga.TYPE_MANHWA }) {
launchUI {
@ -409,7 +226,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
}
}
launchUI {
categories.setState(preferences.hideCategories().getOrDefault())
hide_categories.visibleIf(showCategoriesCheckBox)
// categories.setState(preferences.hideCategories().getOrDefault())
downloaded.setState(preferences.filterDownloaded())
completed.setState(preferences.filterCompleted())
unread.setState(preferences.filterUnread())
@ -421,248 +239,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
}
}
private fun showMainSortOptions() {
// Create a PopupMenu, giving it the clicked view for an anchor
val popup = PopupMenu(context, library_sort_text)
// Inflate our menu resource into the PopupMenu's Menu
popup.menuInflater.inflate(R.menu.main_sort, popup.menu)
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
onMainSortClicked(menuItem.itemId)
true
}
if (popup.menu is MenuBuilder) {
val m = popup.menu as MenuBuilder
m.setOptionalIconsVisible(true)
}
val sortingMode = preferences.librarySortingMode().getOrDefault()
val currentItem = popup.menu.findItem(
when (sortingMode) {
LibrarySort.DRAG_AND_DROP -> R.id.action_drag_and_drop
LibrarySort.TOTAL -> R.id.action_total_chaps
LibrarySort.LAST_READ -> R.id.action_last_read
LibrarySort.UNREAD -> R.id.action_unread
LibrarySort.LAST_UPDATED -> R.id.action_update
else -> R.id.action_alpha
}
)
currentItem.icon = tintVector(
when {
sortingMode == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_check_white_24dp
!preferences.librarySortingAscending().getOrDefault() ->
R.drawable.ic_arrow_down_white_24dp
else -> R.drawable.ic_arrow_up_white_24dp
}
)
// Finally show the PopupMenu
popup.show()
}
private fun showCatSortOptions() {
val category = lastCategory ?: return
// Create a PopupMenu, giving it the clicked view for an anchor
val popup = PopupMenu(context, category_sort_text)
// Inflate our menu resource into the PopupMenu's Menu
popup.menuInflater.inflate(R.menu.cat_sort, popup.menu)
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
onCatSortClicked(menuItem.itemId)
true
}
val sortingMode = category.sortingMode()
val currentItem = if (sortingMode == null) null
else popup.menu.findItem(
when (sortingMode) {
LibrarySort.DRAG_AND_DROP -> R.id.action_drag_and_drop
LibrarySort.TOTAL -> R.id.action_total_chaps
LibrarySort.LAST_READ -> R.id.action_last_read
LibrarySort.UNREAD -> R.id.action_unread
LibrarySort.LAST_UPDATED -> R.id.action_update
else -> R.id.action_alpha
}
)
if (sortingMode != null && popup.menu is MenuBuilder) {
val m = popup.menu as MenuBuilder
m.setOptionalIconsVisible(true)
}
currentItem?.icon = tintVector(
if (category.isAscending()) R.drawable.ic_arrow_up_white_24dp
else R.drawable.ic_arrow_down_white_24dp
)
// Finally show the PopupMenu
popup.show()
}
private fun onMainSortClicked(menuId: Int?) {
if (menuId == null) {
preferences.librarySortingAscending().set(
!preferences.librarySortingAscending().getOrDefault())
}
else {
val sort = when (menuId) {
R.id.action_update -> LibrarySort.LAST_UPDATED
R.id.action_unread -> LibrarySort.UNREAD
R.id.action_total_chaps -> LibrarySort.TOTAL
R.id.action_last_read -> LibrarySort.LAST_READ
R.id.action_drag_and_drop -> LibrarySort.DRAG_AND_DROP
else -> LibrarySort.ALPHA
}
if (sort == preferences.librarySortingMode().getOrDefault()) {
if (sort != LibrarySort.DRAG_AND_DROP)
onMainSortClicked(null)
return
}
preferences.librarySortingMode().set(sort)
preferences.librarySortingAscending().set(true)
}
setMainSortText()
onGroupClicked(ACTION_SORT)
}
private fun onCatSortClicked(menuId: Int?) {
val category = lastCategory ?: return
val modType = if (menuId == null) {
val t = (category.mangaSort?.minus('a') ?: 0) + 1
if (t % 2 != 0) t + 1
else t - 1
}
else {
val order = when (menuId) {
R.id.action_total_chaps -> 4
R.id.action_last_read -> 3
R.id.action_unread -> 2
R.id.action_update -> 1
else -> 0
}
if (order == category.catSortingMode()) {
onCatSortClicked(null)
return
}
(2 * order + 1)
}
launchUI {
withContext(Dispatchers.IO) {
setCatOrder(modType)
}
setCatSortText()
onGroupClicked(ACTION_CAT_SORT)
}
}
private fun setCatOrder(order: Int) {
val category = lastCategory ?: return
category.mangaSort = ('a' + (order - 1))
if (category.id == 0)
preferences.defaultMangaOrder().set(category.mangaSort.toString())
else
Injekt.get<DatabaseHelper>().insertCategory(category).asRxObservable().subscribe()
}
private fun setMainSortText() {
launchUI {
val sortId = withContext(Dispatchers.IO) { sorting(true) }
val drawableL = withContext(Dispatchers.IO) {
tintVector(
when {
sortId == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_sort_white_24dp
preferences.librarySortingAscending().getOrDefault() -> R.drawable.ic_arrow_up_white_24dp
else -> R.drawable.ic_arrow_down_white_24dp
}
)
}
library_sort_text.text = withContext(Dispatchers.IO) {
context.getString(
if (sortId == LibrarySort.DRAG_AND_DROP) R.string.sort_library_by_
else R.string.sort_by_, context.getString(
when (sortId) {
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.DRAG_AND_DROP -> 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
else -> R.string.title
}
)
)
}
library_sort_text.setCompoundDrawablesRelativeWithIntrinsicBounds(
drawableL, null, null, null
)
setCatSortText()
}
}
private fun setCatSortText() {
launchUI {
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP &&
!preferences.hideCategories().getOrDefault() && lastCategory != null) {
val sortId = withContext(Dispatchers.IO) { sorting() }
val drawableL = withContext(Dispatchers.IO) {
tintVector(
when {
sortId == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_label_outline_white_24dp
lastCategory?.isAscending() == true -> R.drawable.ic_arrow_up_white_24dp
else -> R.drawable.ic_arrow_down_white_24dp
}
)
}
category_sort_text.text = withContext(Dispatchers.IO) {
context.getString(
R.string.sort_category_by_, context.getString(
when (sortId) {
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.DRAG_AND_DROP -> 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
else -> R.string.title
}
)
)
}
category_sort_text.setCompoundDrawablesRelativeWithIntrinsicBounds(
drawableL, null, null, null
)
if (category_sort_text.visibility != View.VISIBLE) category_sort_text.visible()
} else if (category_sort_text.visibility == View.VISIBLE) category_sort_text.gone()
}
}
/**
* Binds a Spinner with a boolean preference.
*/
private fun Spinner.bindToPreference(pref: Preference<Int>) {
onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
pref.set(position)
onGroupClicked(ACTION_DISPLAY)
}
setSelection(pref.getOrDefault(), false)
}
private fun tintVector(resId: Int): Drawable? {
return ContextCompat.getDrawable(context, resId)?.mutate()?.apply {
setTint(context.getResourceColor(android.R.attr.colorAccent))
}
}
override fun onFilterClicked(view: FilterTagGroup, index: Int, updatePreference:Boolean) {
if (updatePreference) {
if (view == categories) {
preferences.hideCategories().set(index == 0)
onGroupClicked(ACTION_REFRESH)
} else {
when (view) {
downloaded -> preferences.filterDownloaded()
unread -> preferences.filterUnread()
@ -671,9 +249,7 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
mangaType -> preferences.filterMangaType()
else -> null
}?.set(index + 1)
onGroupClicked (ACTION_FILTER)
}
updateTitle()
onGroupClicked(ACTION_FILTER)
}
val hasFilters = hasActiveFilters()
if (hasFilters && clearButton.parent == null)
@ -716,45 +292,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
filter_scroll.scrollTo(0, 0)
}
private fun showUnreadMenu() {
val popup = PopupMenu(context, unread_badge)
popup.menuInflater.inflate(R.menu.unread_badge, popup.menu)
popup.menu.getItem(min(preferences.unreadBadgeType().getOrDefault(), 1) + 1).isChecked =
true
popup.setOnMenuItemClickListener { menuItem ->
preferences.unreadBadgeType().set(when (menuItem.itemId) {
R.id.action_no_unread -> -1
R.id.action_any_unread -> 0
else -> 1
})
setUnreadIcon()
onGroupClicked(ACTION_UNREAD_BADGE)
true
}
// Finally show the PopupMenu
popup.show()
}
private fun setUnreadIcon() {
launchUI {
val unreadType = preferences.unreadBadgeType().getOrDefault()
val drawableL = withContext(Dispatchers.IO) {
tintVector(
when (unreadType){
-1 -> R.drawable.ic_check_box_outline_blank_24dp
0 -> R.drawable.ic_unread_circle_white_24dp
else -> R.drawable.ic_looks_two_white_24dp
}
)
}
unread_badge.setCompoundDrawablesRelativeWithIntrinsicBounds(
drawableL, null, null, null
)
}
fun adjustFiltersMargin(downloading: Boolean) {
filter_scroll.updatePaddingRelative(end = (if (downloading) 80 else 20).dpToPx)
}
companion object {

View File

@ -8,6 +8,7 @@ import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
@ -17,6 +18,7 @@ import android.widget.FrameLayout
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.core.graphics.ColorUtils
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.GravityCompat
import com.bluelinelabs.conductor.Conductor
import com.bluelinelabs.conductor.Controller
@ -70,12 +72,15 @@ import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import java.util.Date
import java.util.concurrent.TimeUnit
import kotlin.math.abs
open class MainActivity : BaseActivity(), DownloadServiceListener {
protected lateinit var router: Router
protected var drawerArrow: DrawerArrowDrawable? = null
private var currentGestureDelegate:SwipeGestureInterface? = null
private lateinit var gestureDetector:GestureDetectorCompat
protected open var trulyGoBack = false
@ -116,6 +121,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
finish()
return
}
gestureDetector = GestureDetectorCompat(this, GestureListener())
setContentView(R.layout.main_activity)
@ -485,6 +491,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
gestureDetector.onTouchEvent(ev)
if (ev?.action == MotionEvent.ACTION_DOWN) {
if (snackBar != null && snackBar!!.isShown) {
val sRect = Rect()
@ -535,6 +542,8 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
tabs.setupWithViewPager(null)
}
currentGestureDelegate = to as? SwipeGestureInterface
if (from is SecondaryDrawerController) {
if (secondaryDrawer != null) {
from.cleanupSecondaryDrawer(drawer)
@ -571,7 +580,55 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
}
}
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
override fun onDown(e: MotionEvent): Boolean {
return true
}
override fun onFling(
e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float
): Boolean {
var result = false
try {
val diffY = e2.y - e1.y
val diffX = e2.x - e1.x
if (abs(diffX) > abs(diffY)) {
if (abs(diffX) > Companion.SWIPE_THRESHOLD &&
abs(velocityX) > Companion.SWIPE_VELOCITY_THRESHOLD
&& abs(diffY) <= Companion.SWIPE_THRESHOLD / 2
) {
if (diffX > 0) {
currentGestureDelegate?.onSwipeRight(e1.x, e1.y)
} else {
currentGestureDelegate?.onSwipeLeft(e1.x, e1.y)
}
result = true
}
} else if (abs(diffY) > Companion.SWIPE_THRESHOLD && abs(
velocityY
) > Companion.SWIPE_VELOCITY_THRESHOLD
) {
if (diffY > 0) {
currentGestureDelegate?.onSwipeBottom(e1.x, e1.y)
//onSwipeBottom()
} else {
currentGestureDelegate?.onSwipeTop(e1.x, e1.y)
}
result = true
}
} catch (exception: Exception) {
exception.printStackTrace()
}
return result
}
}
companion object {
private const val SWIPE_THRESHOLD = 100
private const val SWIPE_VELOCITY_THRESHOLD = 100
// Shortcut actions
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"
const val SHORTCUT_RECENTLY_UPDATED = "eu.kanade.tachiyomi.SHOW_RECENTLY_UPDATED"
@ -592,4 +649,11 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
interface BottomNavBarInterface {
fun canChangeTabs(block: () -> Unit): Boolean
}
interface SwipeGestureInterface {
fun onSwipeRight(x: Float, y: Float)
fun onSwipeLeft(x: Float, y: Float)
fun onSwipeTop(x: Float, y: Float)
fun onSwipeBottom(x: Float, y: Float)
}

View File

@ -17,7 +17,6 @@ import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.category.CategoryController
import kotlinx.android.synthetic.main.pref_library_columns.view.*
import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
@ -30,29 +29,6 @@ class SettingsLibraryController : SettingsController() {
titleRes = R.string.pref_category_library
preferenceCategory {
titleRes = R.string.pref_category_library_display
preference {
titleRes = R.string.pref_library_columns
onClick {
LibraryColumnsDialog().showDialog(router)
}
fun getColumnValue(value: Int): String {
return if (value == 0) context.getString(R.string.default_columns)
else value.toString()
}
Observable.combineLatest(preferences.portraitColumns().asObservable(),
preferences.landscapeColumns().asObservable()
) { portraitCols, landscapeCols -> Pair(portraitCols, landscapeCols) }
.subscribeUntilDestroy { (portraitCols, landscapeCols) ->
val portrait = getColumnValue(portraitCols)
val landscape = getColumnValue(landscapeCols)
summary =
"${context.getString(R.string.portrait)}: $portrait, " + "${context.getString(
R.string.landscape
)}: $landscape"
}
}
switchPreference {
key = Keys.libraryAsSingleList

View File

@ -32,7 +32,7 @@ class SettingsMainController : SettingsController() {
}
preference {
iconRes = R.drawable.ic_tune_black_24dp
iconRes = R.drawable.ic_tune_white_24dp
iconTint = tintColor
titleRes = R.string.pref_category_general
onClick { navigateTo(SettingsGeneralController()) }

View File

@ -125,6 +125,10 @@ inline fun View.visibleIf(block: () -> Boolean) {
visibility = if (block()) View.VISIBLE else View.GONE
}
inline fun View.visibleIf(show: Boolean) {
visibility = if (show) View.VISIBLE else View.GONE
}
/**
* Returns a TextDrawable determined by input
*

View File

@ -10,7 +10,16 @@ class AutofitRecyclerView @JvmOverloads constructor(context: Context, attrs: Att
val manager = GridLayoutManager(context, 1)
private var columnWidth = -1
var columnWidth = -1
/* set(value) {
field = value
if (value > 0) {
val count = max(1, measuredWidth / value)
spanCount = count
manager.spanCount = count
}
}*/
var spanCount = 0
set(value) {

View File

@ -4,7 +4,7 @@
<gradient
android:angle="90"
android:startColor="#aa000000"
android:startColor="#cc000000"
android:centerColor="#00000000"
android:endColor="#00ffffff"/>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,12l-2.5,-1.5L15,12L15,4h5v8z"/>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,17v2h6v-2L3,17zM3,5v2h10L13,5L3,5zM13,21v-2h8v-2h-8v-2h-2v6h2zM7,9v2L3,11v2h4v2h2L9,9L7,9zM21,13v-2L11,11v2h10zM15,9h2L17,7h4L21,5h-4L17,3h-2v6z"/>
</vector>

View File

@ -0,0 +1,6 @@
<vector android:height="24dp"
android:tint="?attr/actionBarTintColor"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M3,17v2h6v-2L3,17zM3,5v2h10L13,5L3,5zM13,21v-2h8v-2h-8v-2h-2v6h2zM7,9v2L3,11v2h4v2h2L9,9L7,9zM21,13v-2L11,11v2h10zM15,9h2L17,7h4L21,5h-4L17,3h-2v6z"/>
</vector>

View File

@ -1,229 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_sheet"
style="@style/BottomSheetDialogTheme"
android:layout_width="match_parent"
app:behavior_peekHeight="0dp"
android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_sheet_dialog_fragment"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:orientation="vertical">
<HorizontalScrollView
android:id="@+id/filter_scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:paddingEnd="20dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/filter_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/clear_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="@drawable/round_clear_border"
android:clickable="true"
android:contentDescription="@string/action_clear"
android:focusable="true"
android:padding="3dp"
android:src="@drawable/ic_close_white_24dp"
android:tint="@color/gray_button" />
</LinearLayout>
</HorizontalScrollView>
<HorizontalScrollView
android:id="@+id/sortScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="23dp"
android:paddingEnd="20dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/side_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:gravity="center|start"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/sorting_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:id="@+id/library_sort_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:clickable="true"
android:drawablePadding="6dp"
android:background="@drawable/square_ripple"
android:focusable="true"
android:gravity="center"
android:padding="5dp"
android:text="srgdg"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
<TextView
android:id="@+id/category_sort_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/square_ripple"
android:layout_marginEnd="20dp"
android:padding="5dp"
android:clickable="true"
android:drawablePadding="6dp"
android:focusable="true"
android:gravity="center"
android:text="srgdg"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:id="@+id/display_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="7dp"
android:layout_marginEnd="30dp"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:clickable="true"
android:focusable="true"
android:text="@string/display_as"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorSecondary"
android:textSize="15sp"
android:textStyle="normal" />
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/display_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/library_display"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:gravity="center|start"
>
<CheckBox
android:id="@+id/download_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="@string/action_display_download_badge" />
<TextView
android:id="@+id/unread_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:clickable="true"
android:drawablePadding="6dp"
android:background="@drawable/square_ripple"
android:focusable="true"
android:gravity="start|center"
android:padding="5dp"
android:text="@string/action_display_unread_badge"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_sheet_primary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/title_icon"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:src="@drawable/ic_sort_white_24dp"
app:layout_constraintBottom_toBottomOf="@+id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/title" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="15dp"
android:textAlignment="textStart"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="?attr/actionBarTintColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/title_icon"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet>

View File

@ -1,241 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bottom_sheet"
style="@style/BottomSheetDialogTheme"
android:layout_width="match_parent"
app:behavior_peekHeight="0dp"
android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_sheet_dialog_fragment"
android:orientation="vertical"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:orientation="vertical">
<HorizontalScrollView
android:id="@+id/filter_scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:paddingEnd="20dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/filter_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/clear_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="@drawable/round_clear_border"
android:clickable="true"
android:contentDescription="@string/action_clear"
android:focusable="true"
android:padding="3dp"
android:src="@drawable/ic_close_white_24dp"
android:tint="@color/gray_button" />
</LinearLayout>
</HorizontalScrollView>
<HorizontalScrollView
android:id="@+id/sortScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="23dp"
android:paddingEnd="20dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/side_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:gravity="center|start"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/sorting_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:id="@+id/library_sort_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:clickable="true"
android:drawablePadding="6dp"
android:background="@drawable/square_ripple"
android:focusable="true"
android:gravity="center"
android:padding="5dp"
android:text="srgdg"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
<TextView
android:id="@+id/category_sort_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/square_ripple"
android:layout_marginEnd="20dp"
android:padding="5dp"
android:clickable="true"
android:drawablePadding="6dp"
android:focusable="true"
android:gravity="center"
android:text="srgdg"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:id="@+id/display_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="7dp"
android:layout_marginEnd="30dp"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="14dp"
android:clickable="true"
android:focusable="true"
android:text="@string/display_as"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/display_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/library_display"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:gravity="center|start"
>
<CheckBox
android:id="@+id/download_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="@string/action_display_download_badge" />
<TextView
android:id="@+id/unread_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:clickable="true"
android:drawablePadding="6dp"
android:background="@drawable/square_ripple"
android:focusable="true"
android:gravity="start|center"
android:padding="5dp"
android:text="@string/action_display_unread_badge"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_sheet_primary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/pill"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:src="@drawable/draggable_pill"
android:alpha="0.15"
android:contentDescription="@string/drag_handle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/title_icon"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:src="@drawable/ic_sort_white_24dp"
android:contentDescription="@string/sorting_mode"
app:layout_constraintBottom_toBottomOf="@+id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/title" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="15dp"
android:textAlignment="textStart"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="?attr/actionBarTintColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/title_icon"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet>

View File

@ -29,7 +29,6 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0">
<ImageView
android:id="@+id/cover_thumbnail"
android:layout_width="match_parent"

View File

@ -6,6 +6,6 @@
style="@style/Theme.Widget.GridView.Catalogue"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="140dp"
android:columnWidth="120dp"
android:clipToPadding="false"
tools:listitem="@layout/catalogue_grid_item" />

View File

@ -0,0 +1,156 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/diplay_bottom_sheet"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.core.widget.NestedScrollView
android:id="@+id/settings_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/bottom_sheet"
style="@style/BottomSheetDialogTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_sheet_dialog_fragment"
android:orientation="vertical"
android:paddingTop="12dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/display_as" />
<RadioGroup
android:id="@+id/display_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_display_list" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_display_grid" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/action_display_comfy_grid" />
</RadioGroup>
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/grid_options" />
<RadioGroup
android:id="@+id/grid_size_toggle_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:orientation="horizontal">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/small" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@string/medium" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:text="@string/large" />
</RadioGroup>
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/uniform_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:text="@string/uniform_grid" />
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/badges" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/download_badge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:text="@string/action_display_download_badge" />
<RadioGroup
android:id="@+id/unread_badge_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="12dp"
android:paddingEnd="12dp">
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="@string/hide_unread" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_unread" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/show_unread_count" />
</RadioGroup>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<ImageView
android:id="@+id/close_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="@drawable/round_ripple"
android:layout_gravity="end"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:clickable="true"
android:contentDescription="@string/action_close"
android:focusable="true"
android:src="@drawable/ic_close_white_24dp"
android:tint="@color/gray_button" />
</FrameLayout>

View File

@ -33,7 +33,7 @@
android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingTop="8dp"
android:paddingBottom="18dp"
android:paddingBottom="6dp"
android:paddingEnd="20dp"
android:scrollbars="none">
@ -61,130 +61,35 @@
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:id="@+id/side_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:paddingStart="23dp"
android:paddingEnd="20dp"
android:baselineAligned="true"
android:gravity="center|start"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="23dp"
android:orientation="horizontal">
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/hide_categories"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="@string/action_hide_categories" />
<LinearLayout
android:id="@+id/sorting_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:id="@+id/library_sort_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:clickable="true"
android:drawablePadding="6dp"
android:background="@drawable/square_ripple"
android:layout_weight="1"
android:focusable="true"
android:gravity="start|center"
android:padding="5dp"
tools:text="Library Sort"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
<TextView
android:id="@+id/category_sort_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/square_ripple"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:padding="5dp"
android:clickable="true"
android:drawablePadding="6dp"
android:textAlignment="textStart"
android:focusable="true"
android:gravity="start|center"
tools:text="Category Sort"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:id="@+id/display_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="7dp"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"
android:layout_marginEnd="14dp"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:clickable="true"
android:focusable="true"
android:text="@string/display_as"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorSecondary"
android:textSize="15sp"
android:textStyle="normal" />
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/display_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="@array/library_display"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:gravity="center|start"
>
<CheckBox
android:id="@+id/download_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:text="@string/action_display_download_badge" />
<TextView
android:id="@+id/unread_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:clickable="true"
android:drawablePadding="6dp"
android:background="@drawable/square_ripple"
android:focusable="true"
android:gravity="start|center"
android:padding="5dp"
android:text="@string/action_display_unread_badge"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
<TextView
android:layout_marginStart="12dp"
android:id="@+id/reorder_filters"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:clickable="true"
android:background="@drawable/square_ripple"
android:focusable="true"
android:gravity="start|center"
android:padding="10dp"
android:text="Reorder Filters"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
</LinearLayout>
</LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout
@ -207,35 +112,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/title_icon"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:visibility="gone"
android:src="@drawable/ic_sort_white_24dp"
app:layout_constraintBottom_toBottomOf="@+id/title"
android:contentDescription="@string/sorting_mode"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/title" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="15dp"
android:visibility="gone"
android:textAlignment="textStart"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="?attr/actionBarTintColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/title_icon"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet>

View File

@ -35,8 +35,6 @@
android:layout_marginBottom="10dp"
android:ellipsize="end"
android:gravity="center|start"
android:clickable="true"
android:focusable="true"
android:inputType="none"
android:maxLines="2"
android:layout_marginTop="32dp"
@ -46,7 +44,6 @@
app:layout_constraintEnd_toStartOf="@id/update_button"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.0"
android:drawableEnd="@drawable/ic_arrow_drop_down_white_24dp"
tools:text="Title dfdsfsfsfsfsfdsfsfsfs" />
<Space
@ -71,7 +68,6 @@
app:layout_constraintTop_toTopOf="@id/category_title"
app:layout_constraintEnd_toStartOf="@id/space"
app:layout_constraintStart_toEndOf="@id/category_title"
app:layout_constraintWidth_default="wrap"
app:rippleColor="@color/fullRippleColor" />
<TextView

View File

@ -2,7 +2,7 @@
<eu.kanade.tachiyomi.widget.AutofitRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/Theme.Widget.GridView.Catalogue"
android:id="@+id/grid_view"
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="140dp"

View File

@ -5,6 +5,14 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/library_layout"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/recycler_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/library_grid_recycler"/>
</FrameLayout>
<eu.davidea.fastscroller.FastScroller
android:id="@+id/fast_scroller"

View File

@ -5,7 +5,7 @@
<item
android:checked="true"
android:id="@+id/nav_library"
android:icon="@drawable/ic_book_black_24dp"
android:icon="@drawable/ic_collections_bookmark_white_24dp"
android:title="@string/label_library" />
<item
android:id="@+id/nav_recents"

View File

@ -17,4 +17,11 @@
android:title="@string/action_filter"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_library_display"
android:icon="@drawable/ic_tune_white_24dp"
android:title="@string/action_view_options"
app:showAsAction="ifRoom"
/>
</menu>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/reorder_group"
android:checkableBehavior="single">
<item
android:id="@+id/action_no_unread"
android:title="@string/action_display_hide_unread" />
<item
android:id="@+id/action_any_unread"
android:title="@string/action_display_any_unread" />
<item
android:id="@+id/action_all_unread"
android:title="@string/action_display_all_unread" />
</group>
</menu>

View File

@ -35,6 +35,7 @@
<!-- Actions -->
<string name="action_filter">Filter</string>
<string name="action_view_options">View options</string>
<string name="action_filter_downloaded">Downloaded</string>
<string name="action_filter_not_downloaded">Not downloaded</string>
<string name="action_filter_bookmarked">Bookmarked</string>
@ -100,9 +101,6 @@
<string name="action_display_list">List</string>
<string name="action_display_download_badge">Download badges</string>
<string name="action_display_unread_badge">Unread badges</string>
<string name="action_display_all_unread">All unread</string>
<string name="action_display_any_unread">Any unread</string>
<string name="action_display_hide_unread">Hide unread</string>
<string name="action_set_filter">Set filter</string>
<string name="action_cancel">Cancel</string>
<string name="action_sort">Sort</string>
@ -445,6 +443,15 @@
<string name="remember_choice">Remember this choice</string>
<string name="already_in_category">Manga already in category</string>
<string name="category">Category</string>
<string name="uniform_grid">Uniform Grid</string>
<string name="small">Small</string>
<string name="medium">Medium</string>
<string name="large">Large</string>
<string name="grid_options">Grid options</string>
<string name="badges">Badges</string>
<string name="hide_unread">Hide unread badges</string>
<string name="show_unread">Show unread badges</string>
<string name="show_unread_count">Show unread count</string>
<!-- Catalogue fragment -->