From c002a23da29137c2be96420f3a0f2f55b29e52b8 Mon Sep 17 00:00:00 2001 From: Jays2Kings Date: Fri, 16 Apr 2021 02:36:58 -0400 Subject: [PATCH] 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 --- .../data/preference/PreferenceKeys.kt | 2 + .../data/preference/PreferencesHelper.kt | 2 + .../tachiyomi/ui/library/LibraryController.kt | 81 ++++++++----- .../ui/library/display/LibraryCategoryView.kt | 113 +++++++++++++++--- .../display/TabbedLibraryDisplaySheet.kt | 22 +++- .../ui/library/filter/FilterBottomSheet.kt | 86 ++----------- .../main/res/layout/filter_bottom_sheet.xml | 32 ----- .../res/layout/library_category_layout.xml | 48 ++++++-- app/src/main/res/values/arrays.xml | 13 ++ app/src/main/res/values/strings.xml | 3 +- 10 files changed, 234 insertions(+), 168 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index f313e029de..58d97903c0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -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" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 68fd2791a2..436636fa5d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 81db2bf4b9..4f93d90332 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt index e8e8404701..350bf1e020 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/LibraryCategoryView.kt @@ -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(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 + } + ) } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt index 3ec47e2869..295e602267 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/display/TabbedLibraryDisplaySheet.kt @@ -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().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 = listOf( R.string.display, R.string.badges, - R.string.categories + R.string.more ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt index b0ee40b262..c35d18aa6e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt @@ -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) diff --git a/app/src/main/res/layout/filter_bottom_sheet.xml b/app/src/main/res/layout/filter_bottom_sheet.xml index 3a1af5a8e3..812842fbfc 100644 --- a/app/src/main/res/layout/filter_bottom_sheet.xml +++ b/app/src/main/res/layout/filter_bottom_sheet.xml @@ -82,37 +82,6 @@ app:icon="@drawable/ic_label_outline_24dp" app:iconTint="?android:attr/textColorPrimary" /> - - - - - - - - diff --git a/app/src/main/res/layout/library_category_layout.xml b/app/src/main/res/layout/library_category_layout.xml index f37c7d40f9..a11e6e9572 100644 --- a/app/src/main/res/layout/library_category_layout.xml +++ b/app/src/main/res/layout/library_category_layout.xml @@ -1,7 +1,8 @@ - + + + + - + android:maxLines="2" + android:entries="@array/hide_hopper" + app:title="@string/hide_category_hopper" /> - + android:maxLines="2" + android:entries="@array/hopper_long_press" + app:title="@string/category_hopper_long_press" /> + \ No newline at end of file diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 1edc17fa10..982f4be985 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -17,6 +17,19 @@ @string/smart_by_theme + + @string/search + @string/expand_collapse_all_categories + @string/display_options + @string/group_library_by + + + + @string/never + @string/hides_on_scroll + @string/always + + @string/fit_screen @string/stretch diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3bb84cb425..4a501d33a0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -120,6 +120,8 @@ No matches found for your current filters Show all categories Always show current category + Category hopper long-press action + Expand/collapse all categories Expand all categories Collapse all categories Reorder filters @@ -163,7 +165,6 @@ Tap the Library icon to show filters Display as Hide category hopper - Hide category hopper on scroll More library settings Shift one page over Shift double pages