Moving buttons in library filter sheet to display options + new settings

Option to change what hopper long press does (search, expand/collapse, display options, group library)
Also moving hide hopper/ hide hopper on scroll into one spinner
This commit is contained in:
Jays2Kings 2021-04-16 02:36:58 -04:00
parent 8f2a5e1453
commit c002a23da2
10 changed files with 234 additions and 168 deletions

View File

@ -140,6 +140,8 @@ object PreferenceKeys {
const val autoHideHopper = "autohide_hopper"
const val hopperLongPress = "hopper_long_press"
const val onlySearchPinned = "only_search_pinned"
const val downloadNew = "download_new"

View File

@ -342,6 +342,8 @@ class PreferencesHelper(val context: Context) {
fun filterOrder() = flowPrefs.getString("filter_order", "rudcmt")
fun hopperLongPressAction() = flowPrefs.getInt(Keys.hopperLongPress, 0)
fun hideHopper() = flowPrefs.getBoolean("hide_hopper", false)
fun autohideHopper() = flowPrefs.getBoolean(Keys.autoHideHopper, true)

View File

@ -99,6 +99,10 @@ import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.EndAnimatorListener
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -144,6 +148,8 @@ class LibraryController(
var singleCategory: Boolean = false
private set
val scope = CoroutineScope(Job() + Dispatchers.Main)
/**
* Library search query.
*/
@ -376,6 +382,35 @@ class LibraryController(
filterTooltip?.show()
}
private fun showGroupOptions() {
val groupItems = mutableListOf(BY_DEFAULT, BY_TAG, BY_SOURCE, BY_STATUS)
if (presenter.isLoggedIntoTracking) {
groupItems.add(BY_TRACK_STATUS)
}
if (presenter.allCategories.size > 1) {
groupItems.add(UNGROUPED)
}
val items = groupItems.map { id ->
MaterialMenuSheet.MenuSheetItem(
id,
LibraryGroup.groupTypeDrawableRes(id),
LibraryGroup.groupTypeStringRes(id, presenter.allCategories.size > 1)
)
}
MaterialMenuSheet(
activity!!,
items,
activity!!.getString(R.string.group_library_by),
presenter.groupType
) { _, item ->
preferences.groupLibraryBy().set(item)
presenter.groupType = item
shouldScrollToTop = true
presenter.getLibrary()
true
}.show()
}
private fun showDisplayOptions() {
if (displaySheet == null) {
displaySheet = TabbedLibraryDisplaySheet(this)
@ -523,34 +558,7 @@ class LibraryController(
FilterBottomSheet.ACTION_HIDE_FILTER_TIP -> showFilterTip()
FilterBottomSheet.ACTION_DISPLAY -> showDisplayOptions()
FilterBottomSheet.ACTION_EXPAND_COLLAPSE_ALL -> presenter.toggleAllCategoryVisibility()
FilterBottomSheet.ACTION_GROUP_BY -> {
val groupItems = mutableListOf(BY_DEFAULT, BY_TAG, BY_SOURCE, BY_STATUS)
if (presenter.isLoggedIntoTracking) {
groupItems.add(BY_TRACK_STATUS)
}
if (presenter.allCategories.size > 1) {
groupItems.add(UNGROUPED)
}
val items = groupItems.map { id ->
MaterialMenuSheet.MenuSheetItem(
id,
LibraryGroup.groupTypeDrawableRes(id),
LibraryGroup.groupTypeStringRes(id, presenter.allCategories.size > 1)
)
}
MaterialMenuSheet(
activity!!,
items,
activity!!.getString(R.string.group_library_by),
presenter.groupType
) { _, item ->
preferences.groupLibraryBy().set(item)
presenter.groupType = item
shouldScrollToTop = true
presenter.getLibrary()
true
}.show()
}
FilterBottomSheet.ACTION_GROUP_BY -> showGroupOptions()
}
}
}
@ -589,7 +597,15 @@ class LibraryController(
}
binding.roundedCategoryHopper.categoryButton.setOnLongClickListener {
activityBinding?.toolbar?.menu?.performIdentifierAction(R.id.action_search, 0)
when (preferences.hopperLongPressAction().get()) {
3 -> showGroupOptions()
2 -> showDisplayOptions()
1 -> presenter.toggleAllCategoryVisibility()
else -> activityBinding?.toolbar?.menu?.performIdentifierAction(
R.id.action_search,
0
)
}
true
}
@ -823,6 +839,7 @@ class LibraryController(
override fun onDestroy() {
if (::presenter.isInitialized) presenter.onDestroy()
scope.cancel()
super.onDestroy()
}
@ -873,12 +890,14 @@ class LibraryController(
binding.categoryHopperFrame.visibleIf(!singleCategory && !preferences.hideHopper().get())
binding.filterBottomSheet.filterBottomSheet.updateButtons(
showExpand = !singleCategory && presenter.showAllCategories,
groupType = presenter.groupType
)
adapter.isLongPressDragEnabled = canDrag()
binding.categoryRecycler.setCategories(presenter.categories)
binding.filterBottomSheet.filterBottomSheet.setExpandText(preferences.collapsedCategories().getOrDefault().isNotEmpty())
displaySheet?.setExpandText(
showExpanded = !singleCategory && presenter.showAllCategories,
allExpanded = preferences.collapsedCategories().getOrDefault().isNotEmpty()
)
if (shouldScrollToTop) {
binding.libraryGridRecycler.recycler.scrollToPosition(0)
shouldScrollToTop = false

View File

@ -1,32 +1,115 @@
package eu.kanade.tachiyomi.ui.library.display
import android.content.Context
import android.graphics.drawable.AnimatedVectorDrawable
import android.util.AttributeSet
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.LibraryCategoryLayoutBinding
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
import eu.kanade.tachiyomi.ui.library.filter.ManageFilterItem
import eu.kanade.tachiyomi.util.bindToPreference
import eu.kanade.tachiyomi.util.system.toInt
import eu.kanade.tachiyomi.widget.BaseLibraryDisplayView
import kotlin.math.min
class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
BaseLibraryDisplayView<LibraryCategoryLayoutBinding>(context, attrs) {
override fun inflateBinding() = LibraryCategoryLayoutBinding.bind(this)
override fun initGeneralPreferences() {
binding.showAll.bindToPreference(preferences.showAllCategories()) {
controller.presenter.getLibrary()
binding.categoryShow.isEnabled = it
with(binding) {
showAll.bindToPreference(preferences.showAllCategories()) {
controller.presenter.getLibrary()
binding.categoryShow.isEnabled = it
}
categoryShow.isEnabled = showAll.isChecked
categoryShow.bindToPreference(preferences.showCategoryInTitle()) {
controller.showMiniBar()
}
val hideHopper = min(
2,
preferences.hideHopper().get().toInt() * 2 + preferences.autohideHopper().get()
.toInt()
)
hideHopperSpinner.setSelection(hideHopper)
hideHopperSpinner.onItemSelectedListener = {
preferences.hideHopper().set(it == 2)
preferences.autohideHopper().set(it == 1)
controller.hideHopper(it == 2)
controller.resetHopperY()
}
addCategoriesButton.setOnClickListener {
controller.showCategoriesController()
}
expandCollapseCategories.setOnClickListener {
controller.binding.filterBottomSheet.root
.onGroupClicked(FilterBottomSheet.ACTION_EXPAND_COLLAPSE_ALL)
}
hopperLongPress.bindToPreference(preferences.hopperLongPressAction())
reorderFiltersButton.setOnClickListener {
val recycler = RecyclerView(context)
var filterOrder = preferences.filterOrder().get()
if (filterOrder.count() != 6) {
filterOrder = "urdcmt"
}
val adapter = FlexibleAdapter(
filterOrder.toCharArray().map(::ManageFilterItem),
this,
true
)
recycler.layoutManager = LinearLayoutManager(context)
recycler.adapter = adapter
adapter.isHandleDragEnabled = true
adapter.isLongPressDragEnabled = true
MaterialDialog(context).title(R.string.reorder_filters)
.customView(view = recycler, scrollable = false)
.negativeButton(android.R.string.cancel)
.positiveButton(android.R.string.ok) {
val order = adapter.currentItems.map { it.char }.joinToString("")
preferences.filterOrder().set(order)
recycler.adapter = null
}
.show()
}
}
binding.categoryShow.isEnabled = binding.showAll.isChecked
binding.categoryShow.bindToPreference(preferences.showCategoryInTitle()) {
controller.showMiniBar()
}
binding.hideHopper.bindToPreference(preferences.hideHopper()) {
controller.hideHopper(it)
}
binding.autoHideHopper.bindToPreference(preferences.autohideHopper()) {
controller.resetHopperY()
}
binding.addCategoriesButton.setOnClickListener {
controller.showCategoriesController()
}
fun showExpandCategories(show: Boolean) {
binding.expandCollapseCategories.isVisible = show
}
fun setExpandText(expand: Boolean, animated: Boolean = true) {
binding.expandCollapseCategories.setText(
if (expand) {
R.string.expand_all_categories
} else {
R.string.collapse_all_categories
}
)
if (animated) {
binding.expandCollapseCategories.setIconResource(
if (expand) {
R.drawable.anim_expand_less_to_more
} else {
R.drawable.anim_expand_more_to_less
}
)
(binding.expandCollapseCategories.icon as? AnimatedVectorDrawable)?.start()
} else {
binding.expandCollapseCategories.setIconResource(
if (expand) {
R.drawable.ic_expand_more_24dp
} else {
R.drawable.ic_expand_less_24dp
}
)
}
}
}

View File

@ -4,11 +4,16 @@ import android.view.View
import android.view.View.inflate
import androidx.core.content.ContextCompat
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.ui.library.LibraryController
import eu.kanade.tachiyomi.ui.setting.SettingsLibraryController
import eu.kanade.tachiyomi.util.view.compatToolTipText
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.withFadeTransaction
import eu.kanade.tachiyomi.widget.TabbedBottomSheetDialog
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
TabbedBottomSheetDialog(controller.activity!!) {
@ -22,9 +27,7 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
badgesView.controller = controller
categoryView.controller = controller
binding.menu.visible()
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
binding.menu.tooltipText = context.getString(R.string.more_library_settings)
}
binding.menu.compatToolTipText = context.getString(R.string.more_library_settings)
binding.menu.setImageDrawable(
ContextCompat.getDrawable(
context,
@ -35,6 +38,17 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
controller.router.pushController(SettingsLibraryController().withFadeTransaction())
dismiss()
}
setExpandText(
!controller.singleCategory && controller.presenter.showAllCategories,
Injekt.get<PreferencesHelper>().collapsedCategories().getOrDefault().isNotEmpty(),
false
)
}
fun setExpandText(showExpanded: Boolean, allExpanded: Boolean, animated: Boolean = true) {
categoryView.showExpandCategories(showExpanded)
categoryView.setExpandText(allExpanded, animated)
}
override fun dismiss() {
@ -51,6 +65,6 @@ open class TabbedLibraryDisplaySheet(val controller: LibraryController) :
override fun getTabTitles(): List<Int> = listOf(
R.string.display,
R.string.badges,
R.string.categories
R.string.more
)
}

View File

@ -6,12 +6,7 @@ import android.util.AttributeSet
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
@ -25,17 +20,17 @@ import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.collapse
import eu.kanade.tachiyomi.util.view.gone
import eu.kanade.tachiyomi.util.view.hide
import eu.kanade.tachiyomi.util.view.inflate
import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.isHidden
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.view.visible
import eu.kanade.tachiyomi.util.view.visibleIf
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import uy.kohesive.injekt.Injekt
@ -132,35 +127,13 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
)
post {
if (binding.secondLayout.width + binding.firstLayout.width + 20.dpToPx < width) {
binding.secondLayout.removeView(binding.viewOptions)
binding.secondLayout.removeView(binding.reorderFilters)
binding.firstLayout.addView(binding.reorderFilters)
binding.firstLayout.addView(binding.viewOptions)
binding.secondLayout.gone()
} else if (binding.reorderFilters.parent == binding.firstLayout) {
binding.firstLayout.removeView(binding.viewOptions)
binding.firstLayout.removeView(binding.reorderFilters)
binding.secondLayout.addView(binding.reorderFilters)
binding.secondLayout.addView(binding.viewOptions)
binding.secondLayout.visible()
}
}
sheetBehavior?.hide()
binding.expandCategories.setOnClickListener {
onGroupClicked(ACTION_EXPAND_COLLAPSE_ALL)
}
binding.groupBy.setOnClickListener {
onGroupClicked(ACTION_GROUP_BY)
}
binding.viewOptions.setOnClickListener {
onGroupClicked(ACTION_DISPLAY)
}
binding.reorderFilters.setOnClickListener {
manageFilterPopup()
}
val activeFilters = hasActiveFiltersFromPref()
if (activeFilters && sheetBehavior.isHidden() && sheetBehavior?.skipCollapsed == false) {
@ -181,23 +154,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
createTags()
clearButton.setOnClickListener { clearFilters() }
}
fun setExpandText(expand: Boolean) {
binding.expandCategories.setText(
if (expand) {
R.string.expand_all_categories
} else {
R.string.collapse_all_categories
preferences.filterOrder().asFlow()
.drop(1)
.onEach {
filterOrder = it
clearFilters()
}
)
binding.expandCategories.setIconResource(
if (expand) {
R.drawable.ic_expand_less_24dp
} else {
R.drawable.ic_expand_more_24dp
}
)
.launchIn(controller.scope)
}
private fun stateChanged(state: Int) {
@ -383,33 +347,6 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
}
fun manageFilterPopup() {
val recycler = RecyclerView(context)
if (filterOrder.count() != 6) {
filterOrder = "urdcmt"
}
val adapter = FlexibleAdapter(
filterOrder.toCharArray().map(::ManageFilterItem),
this,
true
)
recycler.layoutManager = LinearLayoutManager(context)
recycler.adapter = adapter
adapter.isHandleDragEnabled = true
adapter.isLongPressDragEnabled = true
MaterialDialog(context).title(R.string.reorder_filters)
.customView(view = recycler, scrollable = false)
.negativeButton(android.R.string.cancel)
.positiveButton(android.R.string.ok) {
val order = adapter.currentItems.map { it.char }.joinToString("")
preferences.filterOrder().set(order)
filterOrder = order
clearFilters()
recycler.adapter = null
}
.show()
}
private fun mapOfFilters(char: Char): FilterTagGroup? {
return when (char) {
'u' -> unreadProgress
@ -478,12 +415,11 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
}
}
fun updateButtons(showExpand: Boolean, groupType: Int) {
binding.expandCategories.visibleIf(showExpand && groupType == 0)
fun updateButtons(groupType: Int) {
binding.groupBy.setIconResource(LibraryGroup.groupTypeDrawableRes(groupType))
}
private fun clearFilters() {
fun clearFilters() {
preferences.filterDownloaded().set(0)
preferences.filterUnread().set(0)
preferences.filterCompleted().set(0)

View File

@ -82,37 +82,6 @@
app:icon="@drawable/ic_label_outline_24dp"
app:iconTint="?android:attr/textColorPrimary" />
<com.google.android.material.button.MaterialButton
android:id="@+id/expand_categories"
style="@style/Theme.Widget.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="@string/expand_all_categories"
android:textColor="?android:attr/textColorPrimary"
app:icon="@drawable/ic_expand_more_24dp"
app:iconTint="?android:attr/textColorPrimary" />
</LinearLayout>
<LinearLayout
android:id="@+id/second_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/reorder_filters"
style="@style/Theme.Widget.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:maxLines="2"
android:text="@string/reorder_filters"
android:textColor="?android:attr/textColorPrimary"
app:icon="@drawable/ic_swap_vert_24dp"
app:iconTint="?android:attr/textColorPrimary" />
<com.google.android.material.button.MaterialButton
android:id="@+id/view_options"
style="@style/Theme.Widget.Button.TextButton"
@ -124,7 +93,6 @@
android:textColor="?android:attr/textColorPrimary"
app:icon="@drawable/ic_tune_24dp"
app:iconTint="?android:attr/textColorPrimary" />
</LinearLayout>
</LinearLayout>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<eu.kanade.tachiyomi.ui.library.display.LibraryCategoryView
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
<eu.kanade.tachiyomi.ui.library.display.LibraryCategoryView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<LinearLayout
@ -10,6 +11,28 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/reorder_filters_button"
android:layout_marginStart="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_swap_vert_24dp"
style="@style/Theme.Widget.Button.TextButton"
android:textColor="?android:attr/textColorPrimary"
app:iconTint="?android:attr/textColorPrimary"
android:text="@string/reorder_filters" />
<com.google.android.material.button.MaterialButton
android:id="@+id/expand_collapse_categories"
style="@style/Theme.Widget.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_expand_more_24dp"
android:layout_marginStart="8dp"
android:textColor="?android:attr/textColorPrimary"
app:iconTint="?android:attr/textColorPrimary"
android:text="@string/expand_all_categories" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/category_show"
android:layout_width="match_parent"
@ -26,21 +49,25 @@
android:layout_marginEnd="12dp"
android:text="@string/show_all_categories" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/hide_hopper"
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/hide_hopper_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginStart="18dp"
android:layout_marginEnd="12dp"
android:text="@string/hide_category_hopper" />
android:maxLines="2"
android:entries="@array/hide_hopper"
app:title="@string/hide_category_hopper" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/auto_hide_hopper"
<eu.kanade.tachiyomi.widget.MaterialSpinnerView
android:id="@+id/hopper_long_press"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginStart="18dp"
android:layout_marginEnd="12dp"
android:text="@string/hide_hopper_on_scroll" />
android:maxLines="2"
android:entries="@array/hopper_long_press"
app:title="@string/category_hopper_long_press" />
<com.google.android.material.button.MaterialButton
android:id="@+id/add_categories_button"
@ -48,5 +75,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/add_edit_categories" />
</LinearLayout>
</eu.kanade.tachiyomi.ui.library.display.LibraryCategoryView>

View File

@ -17,6 +17,19 @@
<item>@string/smart_by_theme</item>
</string-array>
<string-array name="hopper_long_press">
<item>@string/search</item>
<item>@string/expand_collapse_all_categories</item>
<item>@string/display_options</item>
<item>@string/group_library_by</item>
</string-array>
<string-array name="hide_hopper">
<item>@string/never</item>
<item>@string/hides_on_scroll</item>
<item>@string/always</item>
</string-array>
<string-array name="image_scale_type">
<item>@string/fit_screen</item>
<item>@string/stretch</item>

View File

@ -120,6 +120,8 @@
<string name="no_matches_for_filters">No matches found for your current filters</string>
<string name="show_all_categories">Show all categories</string>
<string name="always_show_current_category">Always show current category</string>
<string name="category_hopper_long_press">Category hopper long-press action</string>
<string name="expand_collapse_all_categories">Expand/collapse all categories</string>
<string name="expand_all_categories">Expand all categories</string>
<string name="collapse_all_categories">Collapse all categories</string>
<string name="reorder_filters">Reorder filters</string>
@ -163,7 +165,6 @@
<string name="tap_library_to_show_filters">Tap the Library icon to show filters</string>
<string name="display_as">Display as</string>
<string name="hide_category_hopper">Hide category hopper</string>
<string name="hide_hopper_on_scroll">Hide category hopper on scroll</string>
<string name="more_library_settings">More library settings</string>
<string name="shift_one_page_over">Shift one page over</string>
<string name="shift_double_pages">Shift double pages</string>