Added clear all filter button

Starting optimzations to presenter
pull/3117/head
Jay 5 years ago
parent 6973093ea1
commit 362c39056b

@ -4,8 +4,6 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -20,14 +18,14 @@ 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.ui.category.CategoryAdapter import eu.kanade.tachiyomi.ui.category.CategoryAdapter
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.lang.plusAssign
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.doOnApplyWindowInsets import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.inflate import eu.kanade.tachiyomi.util.view.inflate
import eu.kanade.tachiyomi.util.view.snack import eu.kanade.tachiyomi.util.view.snack
import eu.kanade.tachiyomi.util.view.updateLayoutParams import eu.kanade.tachiyomi.util.view.updateLayoutParams
import eu.kanade.tachiyomi.util.view.updatePaddingRelative import eu.kanade.tachiyomi.util.view.updatePaddingRelative
import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.widget.AutofitRecyclerView import eu.kanade.tachiyomi.widget.AutofitRecyclerView
import kotlinx.android.synthetic.main.library_category.view.* import kotlinx.android.synthetic.main.library_category.view.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -80,6 +78,8 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
private var lastClickPosition = -1 private var lastClickPosition = -1
private var justDraggedAndDropped = false
fun onCreate(controller: LibraryController) { fun onCreate(controller: LibraryController) {
this.controller = controller this.controller = controller
@ -231,7 +231,10 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
val mangaForCategory = event.getMangaForCategory(category).orEmpty() val mangaForCategory = event.getMangaForCategory(category).orEmpty()
// Update the category with its manga. // Update the category with its manga.
adapter.setItems(mangaForCategory) if (!justDraggedAndDropped)
adapter.setItems(mangaForCategory)
else
justDraggedAndDropped = false
swipe_refresh.isEnabled = !preferences.hideCategories().getOrDefault() swipe_refresh.isEnabled = !preferences.hideCategories().getOrDefault()
@ -355,7 +358,8 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att
preferences.defaultMangaOrder().set(mangaIds.joinToString("/")) preferences.defaultMangaOrder().set(mangaIds.joinToString("/"))
else else
db.insertCategory(category).asRxObservable().subscribe() db.insertCategory(category).asRxObservable().subscribe()
controller.onSortChanged() justDraggedAndDropped = true
controller.onCatSortChanged(category.id)
controller.enableReorderItems(category) controller.enableReorderItems(category)
} }
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean { override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {

@ -23,6 +23,7 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import com.f2prateek.rx.preferences.Preference import com.f2prateek.rx.preferences.Preference
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayout
@ -225,6 +226,7 @@ class LibraryController(
FilterBottomSheet.ACTION_SORT -> onSortChanged() FilterBottomSheet.ACTION_SORT -> onSortChanged()
FilterBottomSheet.ACTION_DISPLAY -> reattachAdapter() FilterBottomSheet.ACTION_DISPLAY -> reattachAdapter()
FilterBottomSheet.ACTION_BADGE -> onDownloadBadgeChanged() FilterBottomSheet.ACTION_BADGE -> onDownloadBadgeChanged()
FilterBottomSheet.ACTION_CAT_SORT -> onCatSortChanged()
} }
} }
@ -344,11 +346,11 @@ class LibraryController(
} }
tabsVisibilitySubscription?.unsubscribe() tabsVisibilitySubscription?.unsubscribe()
tabsVisibilitySubscription = tabsVisibilityRelay.subscribe { visible -> tabsVisibilitySubscription = tabsVisibilityRelay.subscribe { visible ->
val tabAnimator = (activity as? MainActivity)?.tabAnimator val tabAnimator = (activity as? MainActivity)?.tabAnimator ?: return@subscribe
if (visible) { if (visible && tabAnimator.getHeight() == 0) {
tabAnimator?.expand() tabAnimator.expand()
} else { } else if (!visible && tabAnimator.getHeight() != 0) {
tabAnimator?.collapse() tabAnimator.collapse()
} }
} }
} }
@ -439,11 +441,16 @@ class LibraryController(
/** /**
* Called when the sorting mode is changed. * Called when the sorting mode is changed.
*/ */
fun onSortChanged() { private fun onSortChanged() {
activity?.invalidateOptionsMenu() activity?.invalidateOptionsMenu()
presenter.requestSortUpdate() presenter.requestSortUpdate()
} }
fun onCatSortChanged(id: Int? = null) {
val catId = id ?: adapter?.categories?.getOrNull(library_pager.currentItem)?.id ?: return
presenter.requestCatSortUpdate(catId)
}
/** /**
* Reattaches the adapter to the view pager to recreate fragments * Reattaches the adapter to the view pager to recreate fragments
*/ */
@ -520,6 +527,15 @@ class LibraryController(
this.query = query this.query = query
} }
override fun handleBack(): Boolean {
val sheetBehavior = BottomSheetBehavior.from(bottom_sheet)
if (sheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
return true
}
return super.handleBack()
}
override fun onPrepareOptionsMenu(menu: Menu) { override fun onPrepareOptionsMenu(menu: Menu) {
val navView = navView ?: return val navView = navView ?: return

@ -99,6 +99,8 @@ class LibraryPresenter(
*/ */
private var librarySubscription: Subscription? = null private var librarySubscription: Subscription? = null
private var lastCategoryId:Int? = null
override fun onCreate(savedState: Bundle?) { override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState) super.onCreate(savedState)
subscribeLibrary() subscribeLibrary()
@ -110,19 +112,19 @@ class LibraryPresenter(
fun subscribeLibrary() { fun subscribeLibrary() {
if (librarySubscription.isNullOrUnsubscribed()) { if (librarySubscription.isNullOrUnsubscribed()) {
librarySubscription = getLibraryObservable() librarySubscription = getLibraryObservable()
.combineLatest(downloadTriggerRelay.observeOn(Schedulers.io())) { .combineLatest(downloadTriggerRelay.observeOn(Schedulers.io())) {
lib, _ -> lib.apply { setDownloadCount(mangaMap) } lib, _ -> lib.apply { setDownloadCount(mangaMap) }
} }
.combineLatest(filterTriggerRelay.observeOn(Schedulers.io())) { .combineLatest(filterTriggerRelay.observeOn(Schedulers.io())) {
lib, _ -> lib.copy(mangaMap = applyFilters(lib.mangaMap)) lib, _ -> lib.copy(mangaMap = applyFilters(lib.mangaMap))
} }
.combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) { .combineLatest(sortTriggerRelay.observeOn(Schedulers.io())) {
lib, _ -> lib.copy(mangaMap = applySort(lib.mangaMap)) lib, _ -> lib.copy(mangaMap = applySort(lib.mangaMap))
} }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache({ view, (categories, mangaMap) -> .subscribeLatestCache({ view, (categories, mangaMap) ->
view.onNextLibraryUpdate(categories, mangaMap) view.onNextLibraryUpdate(categories, mangaMap)
}) })
} }
} }
@ -220,12 +222,75 @@ class LibraryPresenter(
} }
} }
private fun applyCatSort(map: LibraryMap, catId: Int?): LibraryMap {
if (catId == null) return map
val categoryManga = map[catId] ?: return map
val catSorted = applySort(mapOf(catId to categoryManga), catId)
val mutableMap = map.toMutableMap()
mutableMap[catId] = catSorted.values.first()
lastCategoryId = null
return mutableMap
}
private fun applySort(map: LibraryMap, catId: Int?): LibraryMap {
if (catId == null) return map
val category = allCategories.find { it.id == catId } ?: return map
val lastReadManga by lazy {
var counter = 0
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
}
val sortFn: (LibraryItem, LibraryItem) -> Int = { i1, i2 ->
val compare = when {
category.mangaSort != null -> {
var sort = when (category.mangaSort) {
ALPHA_ASC, ALPHA_DSC -> sortAlphabetical(i1, i2)
UPDATED_ASC, UPDATED_DSC -> i2.manga.last_update.compareTo(i1.manga.last_update)
UNREAD_ASC, UNREAD_DSC -> when {
i1.manga.unread == i2.manga.unread -> 0
i1.manga.unread == 0 -> if (category.isAscending()) 1 else -1
i2.manga.unread == 0 -> if (category.isAscending()) -1 else 1
else -> i1.manga.unread.compareTo(i2.manga.unread)
}
LAST_READ_ASC, LAST_READ_DSC -> {
val manga1LastRead = lastReadManga[i1.manga.id!!] ?: lastReadManga.size
val manga2LastRead = lastReadManga[i2.manga.id!!] ?: lastReadManga.size
manga1LastRead.compareTo(manga2LastRead)
}
else -> sortAlphabetical(i1, i2)
}
if (!category.isAscending()) sort *= -1
sort
}
category.mangaOrder.isNotEmpty() -> {
val order = category.mangaOrder
val index1 = order.indexOf(i1.manga.id!!)
val index2 = order.indexOf(i2.manga.id!!)
when {
index1 == index2 -> 0
index1 == -1 -> -1
index2 == -1 -> 1
else -> index1.compareTo(index2)
}
}
else -> 0
}
compare
}
val comparator = Comparator(sortFn)
return map.mapValues { entry -> entry.value.sortedWith(comparator) }
}
/** /**
* Applies library sorting to the given map of manga. * Applies library sorting to the given map of manga.
* *
* @param map the map to sort. * @param map the map to sort.
*/ */
private fun applySort(map: LibraryMap): LibraryMap { private fun applySort(map: LibraryMap): LibraryMap {
if (lastCategoryId != null) return applyCatSort(map, lastCategoryId)
val sortingMode = preferences.librarySortingMode().getOrDefault() val sortingMode = preferences.librarySortingMode().getOrDefault()
val lastReadManga by lazy { val lastReadManga by lazy {
@ -415,6 +480,11 @@ class LibraryPresenter(
sortTriggerRelay.call(Unit) sortTriggerRelay.call(Unit)
} }
fun requestCatSortUpdate(catId: Int) {
lastCategoryId = catId
sortTriggerRelay.call(Unit)
}
fun requestFullUpdate() { fun requestFullUpdate() {
librarySubscription?.unsubscribe() librarySubscription?.unsubscribe()
subscribeLibrary() subscribeLibrary()

@ -7,6 +7,7 @@ import android.util.AttributeSet
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RadioButton import android.widget.RadioButton
import android.widget.RadioGroup import android.widget.RadioGroup
@ -69,6 +70,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
var sheetBehavior:BottomSheetBehavior<View>? = null var sheetBehavior:BottomSheetBehavior<View>? = null
private lateinit var clearButton:ImageView
private val filterItems:MutableList<FilterTagGroup> by lazy { private val filterItems:MutableList<FilterTagGroup> by lazy {
val list = mutableListOf<FilterTagGroup>() val list = mutableListOf<FilterTagGroup>()
if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty()) if (Injekt.get<DatabaseHelper>().getCategories().executeAsBlocking().isNotEmpty())
@ -87,9 +90,9 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
fun onCreate(pagerView:View) { fun onCreate(pagerView:View) {
if (context.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) { if (context.resources.configuration?.orientation == Configuration.ORIENTATION_LANDSCAPE) {
sortLayout.orientation = HORIZONTAL sideLayout.orientation = HORIZONTAL
val marginValue = 10.dpToPx val marginValue = 10.dpToPx
arrayListOf(mainSortTextView, catSortTextView, displayLayout).forEach { arrayListOf(sortingLayout).forEach {
it.updateLayoutParams<MarginLayoutParams> { it.updateLayoutParams<MarginLayoutParams> {
bottomMargin = 0 bottomMargin = 0
topMargin = 0 topMargin = 0
@ -100,6 +103,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
top = 0 top = 0
) )
} }
clearButton = pendingClearButton
filterLayout.removeView(clearButton)
sheetBehavior = BottomSheetBehavior.from(this) sheetBehavior = BottomSheetBehavior.from(this)
topbar.setOnClickListener { topbar.setOnClickListener {
if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) { if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) {
@ -110,21 +115,13 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
} }
sortText.alpha = 1f
title.alpha = 0f
pager = pagerView pager = pagerView
pager?.setPadding(0, 0, 0, topbar.height) pager?.setPadding(0, 0, 0, topbar.height)
updateTitle() updateTitle()
sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, progress: Float) { override fun onSlide(bottomSheet: View, progress: Float) {
updateRootPadding(progress) updateRootPadding(progress)
val newProg = when { topbar.alpha = 1 - progress
progress > 0.9f -> 1f
progress < 0.1f -> 0f
else -> progress
}
topbar.alpha = 1 - newProg
} }
override fun onStateChanged(p0: View, state: Int) { override fun onStateChanged(p0: View, state: Int) {
@ -139,8 +136,6 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) { if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius) val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius)
pager?.setPadding(0, 0, 0, topbar.height - height) pager?.setPadding(0, 0, 0, topbar.height - height)
sortText.alpha = 1f
title.alpha = 0f
} }
else { else {
updateRootPadding() updateRootPadding()
@ -150,6 +145,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
mainSortTextView.setOnClickListener { showMainSortOptions() } mainSortTextView.setOnClickListener { showMainSortOptions() }
catSortTextView.setOnClickListener { showCatSortOptions() } catSortTextView.setOnClickListener { showCatSortOptions() }
clearButton.setOnClickListener { clearFilters() }
displayGroup.bindToPreference(preferences.libraryAsList()) displayGroup.bindToPreference(preferences.libraryAsList())
} }
@ -179,7 +175,7 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
LibrarySort.TOTAL -> R.string.action_sort_total LibrarySort.TOTAL -> R.string.action_sort_total
LibrarySort.UNREAD -> R.string.action_filter_unread LibrarySort.UNREAD -> R.string.action_filter_unread
LibrarySort.LAST_READ -> R.string.action_sort_last_read LibrarySort.LAST_READ -> R.string.action_sort_last_read
else -> R.string.action_sort_alpha else -> R.string.title
} }
) )
filters.joinToString(", ") { context.getString(it) } filters.joinToString(", ") { context.getString(it) }
@ -393,9 +389,13 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
} }
(2 * order + 1) (2 * order + 1)
} }
setCatOrder(modType) launchUI {
setCatSortText() withContext(Dispatchers.IO) {
onGroupClicked(ACTION_SORT) setCatOrder(modType)
}
setCatSortText()
onGroupClicked(ACTION_CAT_SORT)
}
} }
private fun setCatOrder(order: Int) { private fun setCatOrder(order: Int) {
@ -425,10 +425,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
drawable, null, null, null drawable, null, null, null
) )
mainSortTextView.text = withContext(Dispatchers.IO) { mainSortTextView.text = withContext(Dispatchers.IO) {
context.getString( if (sortId == LibrarySort.DRAG_AND_DROP)
if (sortId == LibrarySort.DRAG_AND_DROP) R.string.sort_library_by_ context.getString(
else R.string.sort_by_
, context.getString(
when (sortId) { when (sortId) {
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop
@ -438,7 +436,20 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
else -> R.string.title else -> R.string.title
} }
) )
) else {
context.getString(
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
}
)
)
}
} }
setCatSortText() setCatSortText()
} }
@ -450,12 +461,13 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
val sortId = withContext(Dispatchers.IO) { sorting() } val sortId = withContext(Dispatchers.IO) { sorting() }
val drawable = withContext(Dispatchers.IO) { val drawable = withContext(Dispatchers.IO) {
tintVector( tintVector(
when { R.drawable.ic_label_outline_white_24dp
/*when {
sortId == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_sort_white_24dp sortId == LibrarySort.DRAG_AND_DROP -> R.drawable.ic_sort_white_24dp
lastCategory?.isAscending() == true -> R.drawable lastCategory?.isAscending() == true -> R.drawable
.ic_arrow_up_white_24dp .ic_arrow_up_white_24dp
else -> R.drawable.ic_arrow_down_white_24dp else -> R.drawable.ic_arrow_down_white_24dp
} }*/
) )
} }
catSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds( catSortTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(
@ -463,16 +475,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
) )
catSortTextView.text = withContext(Dispatchers.IO) { catSortTextView.text = withContext(Dispatchers.IO) {
context.getString( context.getString(
R.string.sort_category_by_, context.getString( when (sortId) {
when (sortId) { LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated
LibrarySort.LAST_UPDATED -> R.string.action_sort_last_updated LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop
LibrarySort.DRAG_AND_DROP -> R.string.action_sort_drag_and_drop LibrarySort.TOTAL -> R.string.action_sort_total
LibrarySort.TOTAL -> R.string.action_sort_total LibrarySort.UNREAD -> R.string.action_filter_unread
LibrarySort.UNREAD -> R.string.action_filter_unread LibrarySort.LAST_READ -> R.string.action_sort_last_read
LibrarySort.LAST_READ -> R.string.action_sort_last_read else -> R.string.title
else -> R.string.title }
}
)
) )
} }
if (catSortTextView.visibility != View.VISIBLE) catSortTextView.visible() if (catSortTextView.visibility != View.VISIBLE) catSortTextView.visible()
@ -503,38 +513,54 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
override fun onFilterClicked(view: FilterTagGroup, index: Int, updatePreference:Boolean) { override fun onFilterClicked(view: FilterTagGroup, index: Int, updatePreference:Boolean) {
if (updatePreference) { if (updatePreference) {
when (view) { if (view == categories) {
categories -> { preferences.showCategories().set(index != 0)
preferences.showCategories().set(index != 0) onGroupClicked(ACTION_REFRESH)
onGroupClicked(ACTION_REFRESH) } else {
} when (view) {
downloaded -> { downloaded -> preferences.filterDownloaded()
preferences.filterDownloaded().set(index + 1) unread -> preferences.filterUnread()
onGroupClicked(ACTION_FILTER) completed -> preferences.filterCompleted()
} tracked -> preferences.filterTracked()
unread -> { mangaType -> preferences.filterMangaType()
preferences.filterUnread().set(index + 1) else -> null
onGroupClicked(ACTION_FILTER) }?.set(index + 1)
} onGroupClicked (ACTION_FILTER)
completed -> {
preferences.filterCompleted().set(index + 1)
onGroupClicked(ACTION_FILTER)
}
tracked -> {
preferences.filterTracked().set(index + 1)
onGroupClicked(ACTION_FILTER)
}
mangaType -> {
preferences.filterMangaType().set(index + 1)
onGroupClicked(ACTION_FILTER)
}
} }
updateTitle() updateTitle()
} }
val filters = getFilters().size
if (filters > 0 && clearButton.parent == null)
filterLayout.addView(clearButton, 0)
else if (filters == 0 && clearButton.parent != null)
filterLayout.removeView(clearButton)
}
private fun clearFilters() {
val action = if (preferences.showCategories().getOrDefault()) ACTION_REFRESH
else ACTION_FILTER
preferences.showCategories().set(true)
preferences.filterDownloaded().set(0)
preferences.filterUnread().set(0)
preferences.filterCompleted().set(0)
preferences.filterTracked().set(0)
preferences.filterMangaType().set(0)
val transition = androidx.transition.AutoTransition()
transition.duration = 150
androidx.transition.TransitionManager.beginDelayedTransition(filterLayout, transition)
filterItems.forEach {
it.reset()
}
reSortViews()
onGroupClicked(action)
} }
fun reSortViews() { fun reSortViews() {
filterLayout.removeAllViews() filterLayout.removeAllViews()
if (filterItems.any { it.isActivated })
filterLayout.addView(clearButton)
filterItems.filter { it.isActivated }.forEach { filterItems.filter { it.isActivated }.forEach {
filterLayout.addView(it) filterLayout.addView(it)
} }
@ -550,5 +576,6 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
const val ACTION_FILTER = 2 const val ACTION_FILTER = 2
const val ACTION_DISPLAY = 3 const val ACTION_DISPLAY = 3
const val ACTION_BADGE = 4 const val ACTION_BADGE = 4
const val ACTION_CAT_SORT = 5
} }
} }

@ -22,6 +22,7 @@ class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: Attribute
private var root:ViewGroup? = null private var root:ViewGroup? = null
private val buttons by lazy { arrayOf(firstButton, secondButton, thirdButton) } private val buttons by lazy { arrayOf(firstButton, secondButton, thirdButton) }
private val separators by lazy { arrayOf(separator1, separator2) }
override fun isActivated(): Boolean { override fun isActivated(): Boolean {
return buttons.any { it.isActivated } return buttons.any { it.isActivated }
@ -76,6 +77,14 @@ class FilterTagGroup@JvmOverloads constructor(context: Context, attrs: Attribute
toggleButton(0, false) toggleButton(0, false)
} }
fun reset() {
buttons.forEach {
it.isActivated = false
}
for (i in 0 until itemCount) buttons[i].visible()
for (i in 0 until (itemCount - 1)) separators[i].visible()
}
private fun toggleButton(index: Int, callBack: Boolean = true) { private fun toggleButton(index: Int, callBack: Boolean = true) {
if (itemCount == 0) return if (itemCount == 0) return
if (callBack) { if (callBack) {

@ -1,4 +1,4 @@
<vector android:height="24dp" android:tint="#FFFFFF" <vector android:height="24dp" android:tint="?attr/actionBarTintColor"
android:viewportHeight="24.0" android:viewportWidth="24.0" android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/> <path android:fillColor="#FF000000" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/gray_button">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@color/gray_button" />
<corners android:radius="13dp" />
</shape>
</item>
<item android:id="@android:id/background">
<shape
android:shape="rectangle">
<corners android:radius="16dp"/>
<size
android:height="32dp"
android:width="32dp" />
<stroke android:width="1dp" android:color="@color/gray_button" />
</shape>
</item>
</ripple>

@ -15,7 +15,7 @@
<size <size
android:height="32dp" android:height="32dp"
android:width="32dp" /> android:width="32dp" />
<solid android:color="?android:attr/colorBackground"/> <solid android:color="@android:color/transparent"/>
<stroke android:width="1dp" android:color="@color/drawerPrimary" /> <stroke android:width="1dp" android:color="@color/drawerPrimary" />
</shape> </shape>
</item> </item>

@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet xmlns:android="http://schemas.android.com/apk/res/android" <eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottom_sheet" android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
style="@style/BottomSheetDialogTheme" style="@style/BottomSheetDialogTheme"
android:background="@drawable/bg_bottom_sheet_dialog_fragment" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_bottom_sheet_dialog_fragment"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:orientation="vertical" android:orientation="vertical"
@ -16,144 +15,164 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/scrollView" android:id="@+id/scrollView"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
android:orientation="vertical"> <LinearLayout
android:layout_width="match_parent"
<HorizontalScrollView
android:id="@+id/filterScrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:paddingEnd="20dp"
android:paddingBottom="10dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/filterLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
</LinearLayout> android:orientation="vertical">
</HorizontalScrollView>
<HorizontalScrollView <HorizontalScrollView
android:id="@+id/sortScrollView" android:id="@+id/filterScrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="30dp"
android:paddingTop="10dp"
android:paddingEnd="20dp"
android:paddingBottom="10dp"
android:scrollbars="none">
<LinearLayout
android:id="@+id/sortLayout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:baselineAligned="true"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center|start" android:layout_marginTop="6dp"
android:orientation="vertical"> android:clipToPadding="false"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:paddingEnd="20dp"
android:paddingBottom="10dp"
android:scrollbars="none">
<TextView <LinearLayout
android:id="@+id/mainSortTextView" android:id="@+id/filterLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_weight="1"
android:layout_marginBottom="20dp"
android:clickable="true"
android:drawablePadding="16dp"
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" />
<TextView
android:id="@+id/catSortTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="20dp" android:gravity="center_vertical"
android:layout_weight="1" android:orientation="horizontal">
android:layout_marginBottom="20dp"
android:clickable="true" <ImageView
android:drawablePadding="16dp" android:id="@+id/pendingClearButton"
android:gravity="center" android:layout_width="32dp"
android:focusable="true" android:layout_height="32dp"
android:text="srgdg" android:layout_marginStart="10dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2" android:layout_marginEnd="10dp"
android:textColor="?android:attr/textColorPrimary" android:background="@drawable/round_clear_border"
android:textSize="15sp" android:clickable="true"
android:textStyle="normal" /> 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="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:clipToPadding="false"
android:paddingStart="30dp"
android:paddingTop="0dp"
android:paddingEnd="20dp"
android:paddingBottom="10dp"
android:scrollbars="none">
<LinearLayout <LinearLayout
android:id="@+id/displayLayout" android:id="@+id/sideLayout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="true"
android:gravity="center|start" android:gravity="center|start"
android:layout_weight="1" android:orientation="vertical">
android:baselineAligned="false"
android:orientation="horizontal">
<TextView <LinearLayout
android:id="@+id/sortingLayout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="true" android:layout_marginTop="10dp"
android:layout_marginEnd="14dp" android:layout_marginBottom="10dp"
android:focusable="true" android:baselineAligned="false"
android:text="@string/display_as" android:gravity="center|start"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2" android:orientation="horizontal">
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
<RadioGroup <TextView
android:id="@+id/displayGroup" android:id="@+id/mainSortTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:clickable="true"
android:drawablePadding="16dp"
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" />
<TextView
android:id="@+id/catSortTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:clickable="true"
android:drawablePadding="16dp"
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/displayLayout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center|start"
android:orientation="horizontal"> android:orientation="horizontal">
<RadioButton <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="0dp" android:layout_marginEnd="14dp"
android:paddingEnd="8dp" android:clickable="true"
android:text="@string/action_display_grid" /> android:focusable="true"
android:text="@string/display_as"
<RadioButton android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textSize="15sp"
android:textStyle="normal" />
<RadioGroup
android:id="@+id/displayGroup"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:orientation="horizontal">
android:text="@string/action_display_list" />
</RadioGroup> <RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="0dp"
android:paddingEnd="8dp"
android:text="@string/action_display_grid" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="@string/action_display_list" />
</RadioGroup>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </HorizontalScrollView>
</HorizontalScrollView> </LinearLayout>
</LinearLayout> </androidx.core.widget.NestedScrollView>
</androidx.core.widget.NestedScrollView>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/topbar" android:id="@+id/topbar"
@ -162,8 +181,8 @@
android:background="@drawable/bg_bottom_sheet_dialog_fragment" android:background="@drawable/bg_bottom_sheet_dialog_fragment"
android:backgroundTint="?android:attr/colorPrimary" android:backgroundTint="?android:attr/colorPrimary"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintTop_toTopOf="parent">
<ImageView <ImageView
@ -184,7 +203,7 @@
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginBottom="15dp" android:layout_marginBottom="15dp"
android:text="@string/filter_and_sort" android:text="Filter &amp; Sort"
android:textAlignment="textStart" android:textAlignment="textStart"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="?attr/actionBarTintColor" android:textColor="?attr/actionBarTintColor"
@ -192,19 +211,6 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView2" app:layout_constraintStart_toEndOf="@+id/imageView2"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Filter &amp; Sort"
android:textAlignment="textStart"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="?attr/actionBarTintColor"
app:layout_constraintBottom_toBottomOf="@+id/sortText"
app:layout_constraintEnd_toEndOf="@+id/sortText"
app:layout_constraintStart_toStartOf="@+id/sortText"
app:layout_constraintTop_toTopOf="@+id/sortText" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet> </eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet>

@ -31,4 +31,5 @@
<color name="selectorColor">@color/md_blue_A200_50</color> <color name="selectorColor">@color/md_blue_A200_50</color>
<color name="iconColor">@color/md_white_1000_54</color> <color name="iconColor">@color/md_white_1000_54</color>
<color name="button_bg">@color/md_grey_800</color> <color name="button_bg">@color/md_grey_800</color>
<color name="gray_button">#BFBFBF</color>
</resources> </resources>

@ -22,6 +22,7 @@
<color name="readerPrimary">#212121</color> <color name="readerPrimary">#212121</color>
<color name="readerDarkBackground">#1C1C1D</color> <color name="readerDarkBackground">#1C1C1D</color>
<color name="button_bg">@color/md_white_1000</color> <color name="button_bg">@color/md_white_1000</color>
<color name="gray_button">#404040</color>
<color name="textColorPrimary">@color/md_black_1000_87</color> <color name="textColorPrimary">@color/md_black_1000_87</color>
<color name="textColorSecondary">@color/md_black_1000_54</color> <color name="textColorSecondary">@color/md_black_1000_54</color>

@ -51,8 +51,6 @@
<string name="sorting_by_">Sorting by %1$s</string> <string name="sorting_by_">Sorting by %1$s</string>
<string name="sort_by_">Sort by: %1$s</string> <string name="sort_by_">Sort by: %1$s</string>
<string name="sort_library_by_">Sort library by: %1$s</string>
<string name="sort_category_by_">Sort category by: %1$s</string>
<string name="action_filter_empty">Remove filter</string> <string name="action_filter_empty">Remove filter</string>
<string name="action_sort_alpha">Alphabetically</string> <string name="action_sort_alpha">Alphabetically</string>
<string name="action_sort_enabled">Enabled</string> <string name="action_sort_enabled">Enabled</string>
@ -631,7 +629,6 @@
<string name="skip_this_step_next_time">Skip this step next time</string> <string name="skip_this_step_next_time">Skip this step next time</string>
<string name="pre_migration_skip_toast">To show this screen again, go to Settings -> Library.</string> <string name="pre_migration_skip_toast">To show this screen again, go to Settings -> Library.</string>
<string name="reset_tags">Reset Tags</string> <string name="reset_tags">Reset Tags</string>
<string name="filter_and_sort"><![CDATA[Filter & Sort]]></string>
<string name="display_as">Display as:</string> <string name="display_as">Display as:</string>
</resources> </resources>

Loading…
Cancel
Save