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 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 { companion object {
private const val DRAG_AND_DROP = 'D' private const val DRAG_AND_DROP = 'D'
private const val ALPHA_ASC = 'a' private const val ALPHA_ASC = 'a'

View File

@ -113,6 +113,10 @@ object PreferenceKeys {
const val libraryLayout = "pref_display_library_layout" 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 libraryAsSingleList = "library_as_single_list"
const val lang = "app_language" const val lang = "app_language"

View File

@ -173,6 +173,10 @@ class PreferencesHelper(val context: Context) {
fun libraryLayout() = rxPrefs.getInteger(Keys.libraryLayout, 1) 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 libraryAsSingleList() = rxPrefs.getBoolean(Keys.libraryAsSingleList, false)
fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, 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 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) 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) { override fun onPageSelected(position: Int) {
preferences.lastUsedCategory().set(position) preferences.lastUsedCategory().set(position)
activeCategory = position activeCategory = position
bottom_sheet.lastCategory = pagerAdapter?.categories?.getOrNull(position)
if (preferences.librarySortingMode().getOrDefault() == LibrarySort.DRAG_AND_DROP) bottom_sheet.updateTitle()
} }
override fun onPageScrolled( override fun onPageScrolled(
@ -293,7 +291,7 @@ open class LibraryController(
fab.animate().scaleX(scale).scaleY(scale).setDuration(200).start() fab.animate().scaleX(scale).scaleY(scale).setDuration(200).start()
fab.isClickable = downloading fab.isClickable = downloading
fab.isFocusable = downloading fab.isFocusable = downloading
bottom_sheet?.adjustTitleMargin(downloading) bottom_sheet?.adjustFiltersMargin(downloading)
} }
} }
@ -362,9 +360,6 @@ open class LibraryController(
// Restore active category. // Restore active category.
library_pager.setCurrentItem(activeCat, false) library_pager.setCurrentItem(activeCat, false)
bottom_sheet.lastCategory = adapter.categories.getOrNull(activeCat)
bottom_sheet.updateTitle()
tabsVisibilityRelay.call(categories.size > 1) tabsVisibilityRelay.call(categories.size > 1)
libraryMangaRelay.call(LibraryMangaEvent(mangaMap)) libraryMangaRelay.call(LibraryMangaEvent(mangaMap))
@ -430,7 +425,7 @@ open class LibraryController(
/** /**
* Reattaches the adapter to the view pager to recreate fragments * Reattaches the adapter to the view pager to recreate fragments
*/ */
protected open fun reattachAdapter() { open fun reattachAdapter() {
val adapter = pagerAdapter ?: return val adapter = pagerAdapter ?: return
val position = library_pager.currentItem val position = library_pager.currentItem
@ -518,10 +513,14 @@ open class LibraryController(
if (bottom_sheet.sheetBehavior?.isHideable == true && if (bottom_sheet.sheetBehavior?.isHideable == true &&
bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED)
bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN 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 bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
} }
R.id.action_library_display -> {
DisplayBottomSheet(this).show()
}
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
@ -530,7 +529,10 @@ open class LibraryController(
fun showFiltersBottomSheet() { fun showFiltersBottomSheet() {
if (bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_HIDDEN) 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, private val view: View,
adapter: LibraryCategoryAdapter, adapter: LibraryCategoryAdapter,
var width:Int, var width:Int,
compact: Boolean,
private var fixedSize: Boolean private var fixedSize: Boolean
) : LibraryHolder(view, adapter) { ) : LibraryHolder(view, adapter) {
init { init {
play_layout.setOnClickListener { playButtonClicked() } play_layout.setOnClickListener { playButtonClicked() }
if (fixedSize) { if (compact) {
text_layout.gone() text_layout.gone()
} }
else { else {
@ -58,7 +59,7 @@ class LibraryGridHolder(
compact_title.text = title.text compact_title.text = title.text
setUnreadBadge(badge_view, item) 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 View.VISIBLE else View.GONE
// Update the cover. // 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 sortText: TextView = view.findViewById(R.id.category_sort)
private val updateButton: ImageView = view.findViewById(R.id.update_button) private val updateButton: ImageView = view.findViewById(R.id.update_button)
private val checkboxImage: ImageView = view.findViewById(R.id.checkbox) private val checkboxImage: ImageView = view.findViewById(R.id.checkbox)
private val dropDown:Drawable?
init { init {
updateButton.setOnClickListener { addCategoryToUpdate() } updateButton.setOnClickListener { addCategoryToUpdate() }
sortText.setOnClickListener { it.post { showCatSortOptions() } } sortText.setOnClickListener { it.post { showCatSortOptions() } }
checkboxImage.setOnClickListener { selectAll() } checkboxImage.setOnClickListener { selectAll() }
sectionText.setOnClickListener { it.post {
adapter.libraryListener.showCategories(adapterPosition, it)
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
sortText.compoundDrawablesRelative[2]?.mutate()?.setTint( sortText.compoundDrawablesRelative[2]?.mutate()?.setTint(
ContextCompat.getColor(contentView.context, R.color.gray_button)) ContextCompat.getColor(contentView.context, R.color.gray_button))
} }
dropDown = sectionText.compoundDrawablesRelative[2]
updateButton.drawable.mutate() updateButton.drawable.mutate()
} }
@ -99,10 +94,6 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> { sectionText.updateLayoutParams<ConstraintLayout.LayoutParams> {
topMargin = (if (category.isFirst == true) 2 else 32).dpToPx 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 sectionText.text = category.name
sortText.text = itemView.context.getString(R.string.sort_by_, sortText.text = itemView.context.getString(R.string.sort_by_,

View File

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

View File

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

View File

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

View File

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

View File

@ -2,38 +2,24 @@ package eu.kanade.tachiyomi.ui.library.filter
import android.content.Context import android.content.Context
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout 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 com.google.android.material.bottomsheet.BottomSheetBehavior
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper 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.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.track.TrackManager 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.dpToPx
import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.gone import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.inflate 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.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visible import eu.kanade.tachiyomi.util.view.visibleIf
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
import kotlinx.android.synthetic.main.filter_bottom_sheet.view.* import kotlinx.android.synthetic.main.filter_bottom_sheet.view.*
import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -64,18 +50,12 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
private lateinit var tracked: FilterTagGroup private lateinit var tracked: FilterTagGroup
private lateinit var categories: FilterTagGroup // private lateinit var categories: FilterTagGroup
private var mangaType: FilterTagGroup? = null private var mangaType: FilterTagGroup? = null
var lastCategory:Category? = null
var sheetBehavior:BottomSheetBehavior<View>? = null var sheetBehavior:BottomSheetBehavior<View>? = null
var peekHeight = 0
var startingTitle = ""
private lateinit var clearButton:ImageView private lateinit var clearButton:ImageView
private val filterItems:MutableList<FilterTagGroup> by lazy { private val filterItems:MutableList<FilterTagGroup> by lazy {
@ -83,8 +63,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
list.add(downloaded) list.add(downloaded)
list.add(unread) list.add(unread)
list.add(completed) list.add(completed)
if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty()) //if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
list.add(categories) // list.add(categories)
if (Injekt.get<TrackManager>().hasLoggedServices()) if (Injekt.get<TrackManager>().hasLoggedServices())
list.add(tracked) list.add(tracked)
list list
@ -94,22 +74,12 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
var pager:View? = null var pager:View? = null
fun onCreate(pagerView:View) { 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 clearButton = clear_button
filter_layout.removeView(clearButton) filter_layout.removeView(clearButton)
sheetBehavior = BottomSheetBehavior.from(this) sheetBehavior = BottomSheetBehavior.from(this)
val phoneLandscape = (isLandscape() && !isTablet()) val phoneLandscape = (isLandscape() && !isTablet())
sheetBehavior?.isHideable = !phoneLandscape sheetBehavior?.isHideable = true
sheetBehavior?.skipCollapsed = phoneLandscape
top_bar.setOnClickListener { top_bar.setOnClickListener {
if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) { if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) {
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 sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
} }
} }
title.text = startingTitle
pager = pagerView pager = pagerView
updateTitle()
val shadow2:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2) val shadow2:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2)
val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow) val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow)
val snackbarLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout) val snackbarLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout)
if (phoneLandscape) { if (phoneLandscape) {
shadow.alpha = 0f sheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN
sheetBehavior?.peekHeight = 0
} }
sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) { override fun onSlide(bottomSheet: View, progress: Float) {
@ -149,9 +116,9 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
shadow.alpha = 1f shadow.alpha = 1f
pager?.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0) pager?.updatePaddingRelative(bottom = sheetBehavior?.peekHeight ?: 0)
snackbarLayout.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) { if (state == BottomSheetBehavior.STATE_EXPANDED) {
top_bar.alpha = 0f top_bar.alpha = 0f
if (phoneLandscape) if (phoneLandscape)
@ -162,7 +129,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
shadow.alpha = 0f shadow.alpha = 0f
pager?.updatePaddingRelative(bottom = 0) pager?.updatePaddingRelative(bottom = 0)
snackbarLayout.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.isClickable = state == BottomSheetBehavior.STATE_COLLAPSED
//top_bar.isFocusable = 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) { if (phoneLandscape && shadow2.visibility != View.GONE) {
shadow2.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() 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() } 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 { private fun isLandscape(): Boolean {
@ -260,50 +160,6 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE .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) { fun updateRootPadding(progress: Float? = null) {
val minHeight = sheetBehavior?.peekHeight ?: 0 val minHeight = sheetBehavior?.peekHeight ?: 0
val maxHeight = height val maxHeight = height
@ -318,62 +174,19 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
pager?.updatePaddingRelative(bottom = (minHeight * (1 + trueProgress)).toInt()) 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 } 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() { private fun createTags() {
categories = inflate(R.layout.filter_buttons) as FilterTagGroup //categories = inflate(R.layout.filter_buttons) as FilterTagGroup
categories.setup(this, R.string.action_hide_categories) // 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 = inflate(R.layout.filter_buttons) as FilterTagGroup
downloaded.setup(this, R.string.action_filter_downloaded, R.string.action_filter_not_downloaded) 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() { private fun checkForManhwa() {
GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) { GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
val db:DatabaseHelper by injectLazy() val db:DatabaseHelper by injectLazy()
val showCategoriesCheckBox = withContext(Dispatchers.IO) {
db.getCategories().executeAsBlocking()
.isNotEmpty()
}
val librryManga = db.getLibraryMangas().executeAsBlocking() val librryManga = db.getLibraryMangas().executeAsBlocking()
if (librryManga.any { it.mangaType() == Manga.TYPE_MANHWA }) { if (librryManga.any { it.mangaType() == Manga.TYPE_MANHWA }) {
launchUI { launchUI {
@ -409,7 +226,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
} }
} }
launchUI { launchUI {
categories.setState(preferences.hideCategories().getOrDefault()) hide_categories.visibleIf(showCategoriesCheckBox)
// categories.setState(preferences.hideCategories().getOrDefault())
downloaded.setState(preferences.filterDownloaded()) downloaded.setState(preferences.filterDownloaded())
completed.setState(preferences.filterCompleted()) completed.setState(preferences.filterCompleted())
unread.setState(preferences.filterUnread()) 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) { override fun onFilterClicked(view: FilterTagGroup, index: Int, updatePreference:Boolean) {
if (updatePreference) { if (updatePreference) {
if (view == categories) {
preferences.hideCategories().set(index == 0)
onGroupClicked(ACTION_REFRESH)
} else {
when (view) { when (view) {
downloaded -> preferences.filterDownloaded() downloaded -> preferences.filterDownloaded()
unread -> preferences.filterUnread() unread -> preferences.filterUnread()
@ -671,9 +249,7 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
mangaType -> preferences.filterMangaType() mangaType -> preferences.filterMangaType()
else -> null else -> null
}?.set(index + 1) }?.set(index + 1)
onGroupClicked (ACTION_FILTER) onGroupClicked(ACTION_FILTER)
}
updateTitle()
} }
val hasFilters = hasActiveFilters() val hasFilters = hasActiveFilters()
if (hasFilters && clearButton.parent == null) if (hasFilters && clearButton.parent == null)
@ -716,45 +292,8 @@ class SortFilterBottomSheet @JvmOverloads constructor(context: Context, attrs: A
filter_scroll.scrollTo(0, 0) filter_scroll.scrollTo(0, 0)
} }
private fun showUnreadMenu() { fun adjustFiltersMargin(downloading: Boolean) {
val popup = PopupMenu(context, unread_badge) filter_scroll.updatePaddingRelative(end = (if (downloading) 80 else 20).dpToPx)
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
)
}
} }
companion object { companion object {

View File

@ -8,6 +8,7 @@ import android.graphics.Rect
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.view.GestureDetector
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -17,6 +18,7 @@ import android.widget.FrameLayout
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import com.bluelinelabs.conductor.Conductor import com.bluelinelabs.conductor.Conductor
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
@ -70,12 +72,15 @@ import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Date import java.util.Date
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.abs
open class MainActivity : BaseActivity(), DownloadServiceListener { open class MainActivity : BaseActivity(), DownloadServiceListener {
protected lateinit var router: Router protected lateinit var router: Router
protected var drawerArrow: DrawerArrowDrawable? = null protected var drawerArrow: DrawerArrowDrawable? = null
private var currentGestureDelegate:SwipeGestureInterface? = null
private lateinit var gestureDetector:GestureDetectorCompat
protected open var trulyGoBack = false protected open var trulyGoBack = false
@ -116,6 +121,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
finish() finish()
return return
} }
gestureDetector = GestureDetectorCompat(this, GestureListener())
setContentView(R.layout.main_activity) setContentView(R.layout.main_activity)
@ -485,6 +491,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
} }
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
gestureDetector.onTouchEvent(ev)
if (ev?.action == MotionEvent.ACTION_DOWN) { if (ev?.action == MotionEvent.ACTION_DOWN) {
if (snackBar != null && snackBar!!.isShown) { if (snackBar != null && snackBar!!.isShown) {
val sRect = Rect() val sRect = Rect()
@ -535,6 +542,8 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
tabs.setupWithViewPager(null) tabs.setupWithViewPager(null)
} }
currentGestureDelegate = to as? SwipeGestureInterface
if (from is SecondaryDrawerController) { if (from is SecondaryDrawerController) {
if (secondaryDrawer != null) { if (secondaryDrawer != null) {
from.cleanupSecondaryDrawer(drawer) 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 { companion object {
private const val SWIPE_THRESHOLD = 100
private const val SWIPE_VELOCITY_THRESHOLD = 100
// Shortcut actions // Shortcut actions
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY" const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"
const val SHORTCUT_RECENTLY_UPDATED = "eu.kanade.tachiyomi.SHOW_RECENTLY_UPDATED" const val SHORTCUT_RECENTLY_UPDATED = "eu.kanade.tachiyomi.SHOW_RECENTLY_UPDATED"
@ -592,4 +649,11 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
interface BottomNavBarInterface { interface BottomNavBarInterface {
fun canChangeTabs(block: () -> Unit): Boolean 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.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.category.CategoryController
import kotlinx.android.synthetic.main.pref_library_columns.view.* import kotlinx.android.synthetic.main.pref_library_columns.view.*
import rx.Observable
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
@ -30,29 +29,6 @@ class SettingsLibraryController : SettingsController() {
titleRes = R.string.pref_category_library titleRes = R.string.pref_category_library
preferenceCategory { preferenceCategory {
titleRes = R.string.pref_category_library_display 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 { switchPreference {
key = Keys.libraryAsSingleList key = Keys.libraryAsSingleList

View File

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

View File

@ -125,6 +125,10 @@ inline fun View.visibleIf(block: () -> Boolean) {
visibility = if (block()) View.VISIBLE else View.GONE 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 * 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) 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 var spanCount = 0
set(value) { set(value) {

View File

@ -4,7 +4,7 @@
<gradient <gradient
android:angle="90" android:angle="90"
android:startColor="#aa000000" android:startColor="#cc000000"
android:centerColor="#00000000" android:centerColor="#00000000"
android:endColor="#00ffffff"/> 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_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"> app:layout_constraintVertical_bias="1.0">
<ImageView <ImageView
android:id="@+id/cover_thumbnail" android:id="@+id/cover_thumbnail"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -6,6 +6,6 @@
style="@style/Theme.Widget.GridView.Catalogue" style="@style/Theme.Widget.GridView.Catalogue"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:columnWidth="140dp" android:columnWidth="120dp"
android:clipToPadding="false" android:clipToPadding="false"
tools:listitem="@layout/catalogue_grid_item" /> 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:clipToPadding="false"
android:paddingStart="20dp" android:paddingStart="20dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingBottom="18dp" android:paddingBottom="6dp"
android:paddingEnd="20dp" android:paddingEnd="20dp"
android:scrollbars="none"> android:scrollbars="none">
@ -61,130 +61,35 @@
</LinearLayout> </LinearLayout>
</HorizontalScrollView> </HorizontalScrollView>
<LinearLayout <LinearLayout
android:id="@+id/side_layout" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginStart="23dp"
android:layout_marginTop="0dp" android:orientation="horizontal">
android:paddingStart="23dp" <com.google.android.material.checkbox.MaterialCheckBox
android:paddingEnd="20dp" android:id="@+id/hide_categories"
android:baselineAligned="true" android:layout_width="wrap_content"
android:gravity="center|start" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_marginEnd="20dp"
android:text="@string/action_hide_categories" />
<LinearLayout <TextView
android:id="@+id/sorting_layout" android:layout_marginStart="12dp"
android:layout_width="wrap_content" android:id="@+id/reorder_filters"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_marginBottom="10dp" android:layout_height="wrap_content"
android:baselineAligned="false" android:layout_marginEnd="10dp"
android:gravity="center|start" android:clickable="true"
android:orientation="horizontal"> android:background="@drawable/square_ripple"
android:focusable="true"
<TextView android:gravity="start|center"
android:id="@+id/library_sort_text" android:padding="10dp"
android:layout_width="0dp" android:text="Reorder Filters"
android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:layout_marginEnd="10dp" android:textColor="?android:attr/textColorPrimary"
android:clickable="true" android:textSize="15sp"
android:drawablePadding="6dp" android:textStyle="normal" />
android:background="@drawable/square_ripple" </LinearLayout>
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>
</LinearLayout> </LinearLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@ -207,35 +112,6 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="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>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet> </eu.kanade.tachiyomi.ui.library.filter.SortFilterBottomSheet>

View File

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

View File

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

View File

@ -5,6 +5,14 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/library_layout" android:id="@+id/library_layout"
android:layout_height="match_parent"> 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 <eu.davidea.fastscroller.FastScroller
android:id="@+id/fast_scroller" android:id="@+id/fast_scroller"

View File

@ -5,7 +5,7 @@
<item <item
android:checked="true" android:checked="true"
android:id="@+id/nav_library" 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" /> android:title="@string/label_library" />
<item <item
android:id="@+id/nav_recents" android:id="@+id/nav_recents"

View File

@ -17,4 +17,11 @@
android:title="@string/action_filter" android:title="@string/action_filter"
app:showAsAction="ifRoom"/> 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> </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 --> <!-- Actions -->
<string name="action_filter">Filter</string> <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_downloaded">Downloaded</string>
<string name="action_filter_not_downloaded">Not downloaded</string> <string name="action_filter_not_downloaded">Not downloaded</string>
<string name="action_filter_bookmarked">Bookmarked</string> <string name="action_filter_bookmarked">Bookmarked</string>
@ -100,9 +101,6 @@
<string name="action_display_list">List</string> <string name="action_display_list">List</string>
<string name="action_display_download_badge">Download badges</string> <string name="action_display_download_badge">Download badges</string>
<string name="action_display_unread_badge">Unread 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_set_filter">Set filter</string>
<string name="action_cancel">Cancel</string> <string name="action_cancel">Cancel</string>
<string name="action_sort">Sort</string> <string name="action_sort">Sort</string>
@ -445,6 +443,15 @@
<string name="remember_choice">Remember this choice</string> <string name="remember_choice">Remember this choice</string>
<string name="already_in_category">Manga already in category</string> <string name="already_in_category">Manga already in category</string>
<string name="category">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 --> <!-- Catalogue fragment -->