mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-14 05:15:10 +01:00
Jump to category using the backdrop on the top of the library
Along with only showing a single category at a time
This commit is contained in:
parent
49b18181e7
commit
20bab59df3
@ -263,6 +263,8 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun deleteRemovedChapters() = flowPrefs.getInt(Keys.deleteRemovedChapters, 0)
|
fun deleteRemovedChapters() = flowPrefs.getInt(Keys.deleteRemovedChapters, 0)
|
||||||
|
|
||||||
|
fun showAllCategories() = flowPrefs.getBoolean("show_all_categories", true)
|
||||||
|
|
||||||
// Tutorial preferences
|
// Tutorial preferences
|
||||||
fun shownFilterTutorial() = flowPrefs.getBoolean("shown_filter_tutorial", false)
|
fun shownFilterTutorial() = flowPrefs.getBoolean("shown_filter_tutorial", false)
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ import kotlin.math.max
|
|||||||
*
|
*
|
||||||
* @param view the fragment containing this adapter.
|
* @param view the fragment containing this adapter.
|
||||||
*/
|
*/
|
||||||
class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
class LibraryCategoryAdapter(val controller: LibraryController) :
|
||||||
FlexibleAdapter<IFlexible<*>>(null, libraryListener, true) {
|
FlexibleAdapter<IFlexible<*>>(null, controller, true) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setDisplayHeadersAtStartUp(true)
|
setDisplayHeadersAtStartUp(true)
|
||||||
@ -32,6 +32,8 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
|||||||
*/
|
*/
|
||||||
private var mangas: List<LibraryItem> = emptyList()
|
private var mangas: List<LibraryItem> = emptyList()
|
||||||
|
|
||||||
|
val libraryListener: LibraryListener = controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a list of manga in the adapter.
|
* Sets a list of manga in the adapter.
|
||||||
*
|
*
|
||||||
@ -97,13 +99,18 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
|||||||
val preferences: PreferencesHelper by injectLazy()
|
val preferences: PreferencesHelper by injectLazy()
|
||||||
val db: DatabaseHelper by injectLazy()
|
val db: DatabaseHelper by injectLazy()
|
||||||
if (position == itemCount - 1) return "-"
|
if (position == itemCount - 1) return "-"
|
||||||
val sorting = if (preferences.hideCategories().getOrDefault())
|
val sorting = if (!preferences.showAllCategories().get()) {
|
||||||
preferences.hideCategories().getOrDefault()
|
controller.presenter.getCurrentCategory()?.sortingMode() ?: LibrarySort.DRAG_AND_DROP
|
||||||
else (headerItems.firstOrNull() as? LibraryHeaderItem)?.category?.sortingMode()
|
} else if (preferences.hideCategories().getOrDefault()) {
|
||||||
?: LibrarySort.DRAG_AND_DROP
|
preferences.librarySortingMode().getOrDefault()
|
||||||
|
} else {
|
||||||
|
(headerItems.firstOrNull() as? LibraryHeaderItem)?.category?.sortingMode()
|
||||||
|
?: LibrarySort.DRAG_AND_DROP
|
||||||
|
}
|
||||||
return when (val item: IFlexible<*>? = getItem(position)) {
|
return when (val item: IFlexible<*>? = getItem(position)) {
|
||||||
is LibraryHeaderItem ->
|
is LibraryHeaderItem ->
|
||||||
if (preferences.hideCategories().getOrDefault() || item.category.id == 0) null
|
if (preferences.hideCategories().getOrDefault() || item.category.id == 0 ||
|
||||||
|
!preferences.showAllCategories().get()) null
|
||||||
else getFirstChar(item.category.name) +
|
else getFirstChar(item.category.name) +
|
||||||
"\u200B".repeat(max(0, item.category.order))
|
"\u200B".repeat(max(0, item.category.order))
|
||||||
is LibraryItem -> {
|
is LibraryItem -> {
|
||||||
@ -123,11 +130,11 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
|||||||
}
|
}
|
||||||
LibrarySort.TOTAL -> {
|
LibrarySort.TOTAL -> {
|
||||||
val unread = item.chapterCount
|
val unread = item.chapterCount
|
||||||
(unread / 100).toString()
|
getShortRange(unread)
|
||||||
}
|
}
|
||||||
LibrarySort.UNREAD -> {
|
LibrarySort.UNREAD -> {
|
||||||
val unread = item.manga.unread
|
val unread = item.manga.unread
|
||||||
if (unread > 0) (unread / 100).toString()
|
if (unread > 0) getShortRange(unread)
|
||||||
else "R"
|
else "R"
|
||||||
}
|
}
|
||||||
LibrarySort.LATEST_CHAPTER -> {
|
LibrarySort.LATEST_CHAPTER -> {
|
||||||
@ -168,7 +175,9 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
|||||||
else recyclerView.context.getString(R.string.top)
|
else recyclerView.context.getString(R.string.top)
|
||||||
is LibraryItem -> {
|
is LibraryItem -> {
|
||||||
if (iFlexible.manga.isBlank()) ""
|
if (iFlexible.manga.isBlank()) ""
|
||||||
else when (preferences.librarySortingMode().getOrDefault()) {
|
else when (if (!preferences.showAllCategories().get()) {
|
||||||
|
controller.presenter.getCurrentCategory()?.sortingMode() ?: LibrarySort.DRAG_AND_DROP
|
||||||
|
} else preferences.librarySortingMode().getOrDefault()) {
|
||||||
LibrarySort.DRAG_AND_DROP -> {
|
LibrarySort.DRAG_AND_DROP -> {
|
||||||
if (!preferences.hideCategories().getOrDefault()) {
|
if (!preferences.hideCategories().getOrDefault()) {
|
||||||
val title = iFlexible.manga.title
|
val title = iFlexible.manga.title
|
||||||
@ -225,18 +234,36 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getShortRange(value: Int): String {
|
||||||
|
return when (value) {
|
||||||
|
1 -> "1"
|
||||||
|
2 -> "2"
|
||||||
|
3 -> "3"
|
||||||
|
4 -> "4"
|
||||||
|
5 -> "5"
|
||||||
|
in 6..10 -> "6"
|
||||||
|
in 11..50 -> "10"
|
||||||
|
in 51..100 -> "50"
|
||||||
|
in 101..500 -> "1+"
|
||||||
|
in 499..899 -> "4+"
|
||||||
|
in 901..Int.MAX_VALUE -> "9+"
|
||||||
|
else -> "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getRange(value: Int): String {
|
private fun getRange(value: Int): String {
|
||||||
return when (value) {
|
return when (value) {
|
||||||
in 1..99 -> "< 100"
|
1 -> "1"
|
||||||
in 100..199 -> "100-199"
|
2 -> "2"
|
||||||
in 200..299 -> "200-299"
|
3 -> "3"
|
||||||
in 300..399 -> "300-399"
|
4 -> "4"
|
||||||
in 400..499 -> "400-499"
|
5 -> "5"
|
||||||
in 500..599 -> "500-599"
|
in 6..10 -> "6-10"
|
||||||
in 600..699 -> "600-699"
|
in 11..50 -> "11-50"
|
||||||
in 700..799 -> "700-799"
|
in 51..100 -> "51-100"
|
||||||
in 800..899 -> "800-899"
|
in 101..500 -> "100-500"
|
||||||
in 900..Int.MAX_VALUE -> "900+"
|
in 499..899 -> "499-900"
|
||||||
|
in 901..Int.MAX_VALUE -> "900+"
|
||||||
else -> "None"
|
else -> "None"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.library
|
package eu.kanade.tachiyomi.ui.library
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@ -16,6 +17,7 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
|
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
@ -56,10 +58,11 @@ import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
|||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
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.applyWindowInsetsForRootController
|
import eu.kanade.tachiyomi.util.view.applyWindowInsetsForRootController
|
||||||
|
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||||
import eu.kanade.tachiyomi.util.view.getItemView
|
import eu.kanade.tachiyomi.util.view.getItemView
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.hide
|
import eu.kanade.tachiyomi.util.view.hide
|
||||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
import eu.kanade.tachiyomi.util.view.marginTop
|
||||||
import eu.kanade.tachiyomi.util.view.setBackground
|
import eu.kanade.tachiyomi.util.view.setBackground
|
||||||
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||||
import eu.kanade.tachiyomi.util.view.setStartTranslationX
|
import eu.kanade.tachiyomi.util.view.setStartTranslationX
|
||||||
@ -68,6 +71,7 @@ import eu.kanade.tachiyomi.util.view.show
|
|||||||
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.view.visibleIf
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
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_grid_recycler.*
|
||||||
@ -142,7 +146,8 @@ class LibraryController(
|
|||||||
private var scrollAnim: ViewPropertyAnimator? = null
|
private var scrollAnim: ViewPropertyAnimator? = null
|
||||||
private var alwaysShowScroller: Boolean = preferences.alwaysShowSeeker().getOrDefault()
|
private var alwaysShowScroller: Boolean = preferences.alwaysShowSeeker().getOrDefault()
|
||||||
private var filterTooltip: ViewTooltip? = null
|
private var filterTooltip: ViewTooltip? = null
|
||||||
|
private var elevationAnim: ValueAnimator? = null
|
||||||
|
private var elevate = false
|
||||||
override fun getTitle(): String? {
|
override fun getTitle(): String? {
|
||||||
return view?.context?.getString(R.string.library)
|
return view?.context?.getString(R.string.library)
|
||||||
}
|
}
|
||||||
@ -150,6 +155,8 @@ class LibraryController(
|
|||||||
private var scrollListener = object : RecyclerView.OnScrollListener() {
|
private var scrollListener = object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
val notAtTop = recycler.canScrollVertically(-1)
|
||||||
|
if (notAtTop != elevate) elevateFunc(notAtTop)
|
||||||
val order = getCategoryOrder()
|
val order = getCategoryOrder()
|
||||||
if (filter_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_HIDDEN) {
|
if (filter_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_HIDDEN) {
|
||||||
scrollDistance += abs(dy)
|
scrollDistance += abs(dy)
|
||||||
@ -161,6 +168,7 @@ class LibraryController(
|
|||||||
if (order != null && order != activeCategory && lastItem == null) {
|
if (order != null && order != activeCategory && lastItem == null) {
|
||||||
preferences.lastUsedCategory().set(order)
|
preferences.lastUsedCategory().set(order)
|
||||||
activeCategory = order
|
activeCategory = order
|
||||||
|
setActiveCategory()
|
||||||
if (presenter.categories.size > 1 && dy != 0) {
|
if (presenter.categories.size > 1 && dy != 0) {
|
||||||
val headerItem = getHeader() ?: return
|
val headerItem = getHeader() ?: return
|
||||||
val view = fast_scroller?.getChildAt(0) ?: return
|
val view = fast_scroller?.getChildAt(0) ?: return
|
||||||
@ -226,6 +234,12 @@ class LibraryController(
|
|||||||
fast_scroller.setStartTranslationX(!alwaysShowScroller)
|
fast_scroller.setStartTranslationX(!alwaysShowScroller)
|
||||||
fast_scroller.setBackground(!alwaysShowScroller)
|
fast_scroller.setBackground(!alwaysShowScroller)
|
||||||
|
|
||||||
|
show_all.isChecked = preferences.showAllCategories().get()
|
||||||
|
show_all.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
preferences.showAllCategories().set(isChecked)
|
||||||
|
presenter.getLibrary()
|
||||||
|
}
|
||||||
|
|
||||||
adapter = LibraryCategoryAdapter(this)
|
adapter = LibraryCategoryAdapter(this)
|
||||||
adapter.expandItemsAtStartUp()
|
adapter.expandItemsAtStartUp()
|
||||||
adapter.isRecursiveCollapse = true
|
adapter.isRecursiveCollapse = true
|
||||||
@ -243,7 +257,7 @@ class LibraryController(
|
|||||||
recycler.adapter = adapter
|
recycler.adapter = adapter
|
||||||
fast_scroller.setupWithRecyclerView(recycler, { position ->
|
fast_scroller.setupWithRecyclerView(recycler, { position ->
|
||||||
val letter = adapter.getSectionText(position)
|
val letter = adapter.getSectionText(position)
|
||||||
if (!singleCategory &&
|
if (!singleCategory && presenter.showAllCategories &&
|
||||||
!adapter.isHeader(adapter.getItem(position)) &&
|
!adapter.isHeader(adapter.getItem(position)) &&
|
||||||
position != adapter.itemCount - 1) null
|
position != adapter.itemCount - 1) null
|
||||||
else if (letter != null) FastScrollItemIndicator.Text(letter)
|
else if (letter != null) FastScrollItemIndicator.Text(letter)
|
||||||
@ -287,8 +301,7 @@ class LibraryController(
|
|||||||
appbar?.y = 0f
|
appbar?.y = 0f
|
||||||
recycler.suppressLayout(true)
|
recycler.suppressLayout(true)
|
||||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||||
itemPosition,
|
itemPosition, 0
|
||||||
if (singleCategory) 0 else (if (itemPosition == 0) 0 else (-40).dpToPx)
|
|
||||||
)
|
)
|
||||||
recycler.suppressLayout(false)
|
recycler.suppressLayout(false)
|
||||||
}
|
}
|
||||||
@ -298,16 +311,43 @@ class LibraryController(
|
|||||||
val tv = TypedValue()
|
val tv = TypedValue()
|
||||||
activity!!.theme.resolveAttribute(R.attr.actionBarTintColor, tv, true)
|
activity!!.theme.resolveAttribute(R.attr.actionBarTintColor, tv, true)
|
||||||
swipe_refresh.setStyle()
|
swipe_refresh.setStyle()
|
||||||
scrollViewWith(recycler, swipeRefreshLayout = swipe_refresh, afterInsets = { insets ->
|
|
||||||
|
recycler_cover.setOnClickListener {
|
||||||
|
showCategories(false)
|
||||||
|
}
|
||||||
|
category_recycler.onCategoryClicked = {
|
||||||
|
scrollToHeader(it)
|
||||||
|
showCategories(false)
|
||||||
|
}
|
||||||
|
swipe_refresh.setDistanceToTriggerSync(150.dpToPx)
|
||||||
|
val marginTop = category_layout.marginTop
|
||||||
|
recycler.doOnApplyWindowInsets { recyclerView, insets, _ ->
|
||||||
|
recyclerView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
topMargin = marginTop + insets.systemWindowInsetTop
|
||||||
|
}
|
||||||
|
category_layout?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
topMargin = marginTop + insets.systemWindowInsetTop
|
||||||
|
}
|
||||||
|
recycler_cover?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
topMargin = marginTop + insets.systemWindowInsetTop
|
||||||
|
}
|
||||||
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
fast_scroller?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
topMargin = insets.systemWindowInsetTop
|
topMargin = insets.systemWindowInsetTop
|
||||||
}
|
}
|
||||||
})
|
swipe_refresh?.setProgressViewOffset(
|
||||||
|
true, (marginTop + insets.systemWindowInsetTop) + (-60).dpToPx, marginTop + insets.systemWindowInsetTop + 10.dpToPx
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
swipe_refresh.setOnRefreshListener {
|
swipe_refresh.setOnRefreshListener {
|
||||||
swipe_refresh.isRefreshing = false
|
swipe_refresh.isRefreshing = false
|
||||||
if (!LibraryUpdateService.isRunning()) {
|
if (!LibraryUpdateService.isRunning()) {
|
||||||
when {
|
when {
|
||||||
|
!presenter.showAllCategories -> {
|
||||||
|
presenter.categories.find { it.id == presenter.currentCategory }?.let {
|
||||||
|
updateLibrary(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
presenter.allCategories.size <= 1 -> updateLibrary()
|
presenter.allCategories.size <= 1 -> updateLibrary()
|
||||||
preferences.updateOnRefresh().getOrDefault() == -1 -> {
|
preferences.updateOnRefresh().getOrDefault() == -1 -> {
|
||||||
MaterialDialog(activity!!).title(R.string.what_should_update)
|
MaterialDialog(activity!!).title(R.string.what_should_update)
|
||||||
@ -357,7 +397,7 @@ class LibraryController(
|
|||||||
|
|
||||||
presenter.onRestore()
|
presenter.onRestore()
|
||||||
if (presenter.libraryItems.isNotEmpty()) {
|
if (presenter.libraryItems.isNotEmpty()) {
|
||||||
onNextLibraryUpdate(presenter.libraryItems, true)
|
presenter.restoreLibrary()
|
||||||
} else {
|
} else {
|
||||||
recycler_layout.alpha = 0f
|
recycler_layout.alpha = 0f
|
||||||
presenter.getLibrary()
|
presenter.getLibrary()
|
||||||
@ -453,7 +493,13 @@ class LibraryController(
|
|||||||
presenter.getLibrary()
|
presenter.getLibrary()
|
||||||
DownloadService.callListeners()
|
DownloadService.callListeners()
|
||||||
LibraryUpdateService.setListener(this)
|
LibraryUpdateService.setListener(this)
|
||||||
} else closeTip()
|
recycler_cover.isClickable = false
|
||||||
|
recycler_cover.isFocusable = false
|
||||||
|
activity?.dropdown?.visibleIf(!singleCategory)
|
||||||
|
} else {
|
||||||
|
closeTip()
|
||||||
|
activity?.dropdown?.gone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResumed(activity: Activity) {
|
override fun onActivityResumed(activity: Activity) {
|
||||||
@ -482,7 +528,7 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onNextLibraryUpdate(mangaMap: List<LibraryItem>, freshStart: Boolean = false) {
|
fun onNextLibraryUpdate(mangaMap: List<LibraryItem>, freshStart: Boolean = false) {
|
||||||
if (view == null) return
|
val view = view ?: return
|
||||||
destroyActionModeIfNeeded()
|
destroyActionModeIfNeeded()
|
||||||
if (mangaMap.isNotEmpty()) {
|
if (mangaMap.isNotEmpty()) {
|
||||||
empty_view?.hide()
|
empty_view?.hide()
|
||||||
@ -494,8 +540,12 @@ class LibraryController(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
adapter.setItems(mangaMap)
|
adapter.setItems(mangaMap)
|
||||||
|
if (recycler.itemAnimator == null)
|
||||||
|
recycler.post {
|
||||||
|
recycler.itemAnimator = DefaultItemAnimator()
|
||||||
|
}
|
||||||
singleCategory = presenter.categories.size <= 1
|
singleCategory = presenter.categories.size <= 1
|
||||||
|
activity?.dropdown?.visibleIf(!singleCategory)
|
||||||
progress.gone()
|
progress.gone()
|
||||||
if (!freshStart) {
|
if (!freshStart) {
|
||||||
justStarted = false
|
justStarted = false
|
||||||
@ -506,15 +556,69 @@ class LibraryController(
|
|||||||
scrollToHeader(activeCategory)
|
scrollToHeader(activeCategory)
|
||||||
if (!alwaysShowScroller) {
|
if (!alwaysShowScroller) {
|
||||||
fast_scroller?.show(false)
|
fast_scroller?.show(false)
|
||||||
view?.post {
|
view.post {
|
||||||
scrollAnim = fast_scroller?.hide(2000)
|
scrollAnim = fast_scroller?.hide(2000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adapter.isLongPressDragEnabled = canDrag()
|
adapter.isLongPressDragEnabled = canDrag()
|
||||||
|
category_recycler.setCategories(presenter.categories)
|
||||||
|
setActiveCategory()
|
||||||
|
activity?.toolbar?.setOnClickListener {
|
||||||
|
val recycler = recycler ?: return@setOnClickListener
|
||||||
|
if (singleCategory) {
|
||||||
|
recycler.scrollToPosition(0)
|
||||||
|
} else {
|
||||||
|
showCategories(recycler.translationY == 0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showCategories(show: Boolean) {
|
||||||
|
recycler_cover.isClickable = show
|
||||||
|
recycler_cover.isFocusable = show
|
||||||
|
val translateY = if (show) category_layout.height.toFloat() + 12f.dpToPx else 0f
|
||||||
|
recycler.animate().translationY(translateY).start()
|
||||||
|
recycler_cover.animate().translationY(translateY).start()
|
||||||
|
recycler_cover.animate().alpha(if (show) 0.75f else 0f).start()
|
||||||
|
if (show) {
|
||||||
|
elevateFunc(false)
|
||||||
|
activity?.dropdown?.setImageResource(R.drawable.ic_arrow_drop_up_24dp)
|
||||||
|
} else {
|
||||||
|
val notAtTop = recycler.canScrollVertically(-1)
|
||||||
|
if (notAtTop != elevate) elevateFunc(notAtTop)
|
||||||
|
activity?.dropdown?.setImageResource(R.drawable.ic_arrow_drop_down_24dp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun elevateFunc(el: Boolean) {
|
||||||
|
elevate = el
|
||||||
|
elevationAnim?.cancel()
|
||||||
|
elevationAnim = ValueAnimator.ofFloat(
|
||||||
|
activity?.appbar?.elevation ?: 0f, if (el) 15f else 0f
|
||||||
|
)
|
||||||
|
elevationAnim?.addUpdateListener { valueAnimator ->
|
||||||
|
activity?.appbar?.elevation = valueAnimator.animatedValue as Float
|
||||||
|
}
|
||||||
|
elevationAnim?.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setActiveCategory() {
|
||||||
|
val currentCategory = presenter.categories.indexOfFirst {
|
||||||
|
if (presenter.showAllCategories) it.order == activeCategory else presenter.currentCategory == it.id
|
||||||
|
}
|
||||||
|
category_recycler.setCategories(currentCategory)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scrollToHeader(pos: Int) {
|
private fun scrollToHeader(pos: Int) {
|
||||||
|
if (!presenter.showAllCategories) {
|
||||||
|
recycler.itemAnimator = null
|
||||||
|
presenter.switchSection(pos)
|
||||||
|
activeCategory = pos
|
||||||
|
setActiveCategory()
|
||||||
|
recycler.scrollToPosition(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
val headerPosition = adapter.indexOf(pos)
|
val headerPosition = adapter.indexOf(pos)
|
||||||
if (headerPosition > -1) {
|
if (headerPosition > -1) {
|
||||||
val appbar = activity?.appbar
|
val appbar = activity?.appbar
|
||||||
@ -523,7 +627,7 @@ class LibraryController(
|
|||||||
view?.rootWindowInsets?.systemWindowInsetTop ?: 0
|
view?.rootWindowInsets?.systemWindowInsetTop ?: 0
|
||||||
) ?: 0f).roundToInt() + 30.dpToPx
|
) ?: 0f).roundToInt() + 30.dpToPx
|
||||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||||
headerPosition, (if (headerPosition == 0) 0 else (-40).dpToPx) + appbarOffset
|
headerPosition, (if (headerPosition == 0) 0 else (-32).dpToPx) + appbarOffset
|
||||||
)
|
)
|
||||||
recycler.suppressLayout(false)
|
recycler.suppressLayout(false)
|
||||||
}
|
}
|
||||||
@ -815,6 +919,10 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toggleCategoryVisibility(position: Int) {
|
override fun toggleCategoryVisibility(position: Int) {
|
||||||
|
if (!presenter.showAllCategories) {
|
||||||
|
showCategories(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
val catId = (adapter.getItem(position) as? LibraryHeaderItem)?.category?.id ?: return
|
val catId = (adapter.getItem(position) as? LibraryHeaderItem)?.category?.id ?: return
|
||||||
presenter.toggleCategoryVisibility(catId)
|
presenter.toggleCategoryVisibility(catId)
|
||||||
}
|
}
|
||||||
@ -842,6 +950,7 @@ class LibraryController(
|
|||||||
return items.all { adapter.isSelected(it) }
|
return items.all { adapter.isSelected(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//region sheet methods
|
||||||
override fun showSheet() {
|
override fun showSheet() {
|
||||||
closeTip()
|
closeTip()
|
||||||
when {
|
when {
|
||||||
@ -875,6 +984,7 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
//region Toolbar options methods
|
//region Toolbar options methods
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.util.view.invisible
|
|||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
import eu.kanade.tachiyomi.util.view.visInvisIf
|
import eu.kanade.tachiyomi.util.view.visInvisIf
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
|
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||||
import kotlinx.android.synthetic.main.library_category_header_item.*
|
import kotlinx.android.synthetic.main.library_category_header_item.*
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
@ -184,16 +185,16 @@ class LibraryHeaderItem(
|
|||||||
updateButton.gone()
|
updateButton.gone()
|
||||||
}
|
}
|
||||||
LibraryUpdateService.categoryInQueue(category.id) -> {
|
LibraryUpdateService.categoryInQueue(category.id) -> {
|
||||||
expandImage.visible()
|
expandImage.visibleIf(adapter.headerItems.size > 1)
|
||||||
checkboxImage.gone()
|
checkboxImage.gone()
|
||||||
catProgress.visible()
|
catProgress.visible()
|
||||||
updateButton.invisible()
|
updateButton.invisible()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
expandImage.visible()
|
expandImage.visibleIf(adapter.headerItems.size > 1)
|
||||||
catProgress.gone()
|
catProgress.gone()
|
||||||
checkboxImage.gone()
|
checkboxImage.gone()
|
||||||
updateButton.visInvisIf(category.id ?: 0 > -1)
|
updateButton.visInvisIf(category.id ?: 0 > -1 && adapter.headerItems.size > 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,12 @@ class LibraryPresenter(
|
|||||||
|
|
||||||
/** List of all manga to update the */
|
/** List of all manga to update the */
|
||||||
var libraryItems: List<LibraryItem> = emptyList()
|
var libraryItems: List<LibraryItem> = emptyList()
|
||||||
|
private var sectionedLibraryItems: Map<Int, List<LibraryItem>> = emptyMap()
|
||||||
|
var currentCategory = -1
|
||||||
|
private set
|
||||||
private var allLibraryItems: List<LibraryItem> = emptyList()
|
private var allLibraryItems: List<LibraryItem> = emptyList()
|
||||||
|
val showAllCategories
|
||||||
|
get() = preferences.showAllCategories().get()
|
||||||
|
|
||||||
private var totalChapters: Map<Long, Int>? = null
|
private var totalChapters: Map<Long, Int>? = null
|
||||||
|
|
||||||
@ -92,16 +97,56 @@ class LibraryPresenter(
|
|||||||
mangaMap = applyFilters(mangaMap)
|
mangaMap = applyFilters(mangaMap)
|
||||||
mangaMap = applySort(mangaMap)
|
mangaMap = applySort(mangaMap)
|
||||||
val freshStart = libraryItems.isEmpty()
|
val freshStart = libraryItems.isEmpty()
|
||||||
libraryItems = mangaMap
|
sectionLibrary(mangaMap, freshStart)
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view.onNextLibraryUpdate(libraryItems, freshStart)
|
|
||||||
}
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
setTotalChapters()
|
setTotalChapters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getCurrentCategory() = categories.find { it.id == currentCategory }
|
||||||
|
|
||||||
|
fun switchSection(order: Int) {
|
||||||
|
preferences.lastUsedCategory().set(order)
|
||||||
|
val category = categories.find { it.order == order }?.id ?: return
|
||||||
|
currentCategory = category
|
||||||
|
view.onNextLibraryUpdate(sectionedLibraryItems[currentCategory] ?: emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun restoreLibrary() {
|
||||||
|
val items = libraryItems
|
||||||
|
val show = showAllCategories || preferences.hideCategories().getOrDefault()
|
||||||
|
if (!show) {
|
||||||
|
sectionedLibraryItems = items.groupBy { it.manga.category }
|
||||||
|
if (currentCategory == -1) currentCategory = categories.find {
|
||||||
|
it.order == preferences.lastUsedCategory().getOrDefault()
|
||||||
|
}?.id ?: 0
|
||||||
|
}
|
||||||
|
view.onNextLibraryUpdate(
|
||||||
|
if (!show) sectionedLibraryItems[currentCategory]
|
||||||
|
?: sectionedLibraryItems[categories.first().id] ?: emptyList()
|
||||||
|
else libraryItems, true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun sectionLibrary(items: List<LibraryItem>, freshStart: Boolean = false) {
|
||||||
|
libraryItems = items
|
||||||
|
val show = showAllCategories || preferences.hideCategories().getOrDefault()
|
||||||
|
if (!show) {
|
||||||
|
sectionedLibraryItems = items.groupBy { it.manga.category }
|
||||||
|
if (currentCategory == -1) currentCategory = categories.find {
|
||||||
|
it.order == preferences.lastUsedCategory().getOrDefault()
|
||||||
|
}?.id ?: 0
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
view.onNextLibraryUpdate(
|
||||||
|
if (!show) sectionedLibraryItems[currentCategory]
|
||||||
|
?: sectionedLibraryItems[categories.first().id] ?: emptyList()
|
||||||
|
else libraryItems, freshStart
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies library filters to the given list of manga.
|
* Applies library filters to the given list of manga.
|
||||||
*
|
*
|
||||||
@ -402,6 +447,7 @@ class LibraryPresenter(
|
|||||||
val showCategories = !preferences.hideCategories().getOrDefault()
|
val showCategories = !preferences.hideCategories().getOrDefault()
|
||||||
var libraryManga = db.getLibraryMangas().executeAsBlocking()
|
var libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||||
val seekPref = preferences.alwaysShowSeeker()
|
val seekPref = preferences.alwaysShowSeeker()
|
||||||
|
val showAll = showAllCategories
|
||||||
if (!showCategories) libraryManga = libraryManga.distinctBy { it.id }
|
if (!showCategories) libraryManga = libraryManga.distinctBy { it.id }
|
||||||
val categoryAll = Category.createAll(
|
val categoryAll = Category.createAll(
|
||||||
context,
|
context,
|
||||||
@ -430,12 +476,13 @@ class LibraryPresenter(
|
|||||||
if (showCategories) {
|
if (showCategories) {
|
||||||
categories.forEach { category ->
|
categories.forEach { category ->
|
||||||
val catId = category.id ?: return@forEach
|
val catId = category.id ?: return@forEach
|
||||||
if (catId > 0 && !categorySet.contains(catId) && catId !in categoriesHidden) {
|
if (catId > 0 && !categorySet.contains(catId) &&
|
||||||
|
(catId !in categoriesHidden || !showAll)) {
|
||||||
val headerItem = headerItems[catId]
|
val headerItem = headerItems[catId]
|
||||||
if (headerItem != null) items.add(
|
if (headerItem != null) items.add(
|
||||||
LibraryItem(LibraryManga.createBlank(catId), headerItem)
|
LibraryItem(LibraryManga.createBlank(catId), headerItem)
|
||||||
)
|
)
|
||||||
} else if (catId in categoriesHidden) {
|
} else if (catId in categoriesHidden && showAll) {
|
||||||
val mangaToRemove = items.filter { it.manga.category == catId }
|
val mangaToRemove = items.filter { it.manga.category == catId }
|
||||||
val mergedTitle = mangaToRemove.joinToString("-") {
|
val mergedTitle = mangaToRemove.joinToString("-") {
|
||||||
it.manga.title + "-" + it.manga.author
|
it.manga.title + "-" + it.manga.author
|
||||||
@ -450,7 +497,7 @@ class LibraryPresenter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
categories.forEach {
|
categories.forEach {
|
||||||
it.isHidden = it.id in categoriesHidden
|
it.isHidden = it.id in categoriesHidden && showAll
|
||||||
}
|
}
|
||||||
|
|
||||||
this.allCategories = categories
|
this.allCategories = categories
|
||||||
@ -476,10 +523,7 @@ class LibraryPresenter(
|
|||||||
var mangaMap = allLibraryItems
|
var mangaMap = allLibraryItems
|
||||||
mangaMap = applyFilters(mangaMap)
|
mangaMap = applyFilters(mangaMap)
|
||||||
mangaMap = applySort(mangaMap)
|
mangaMap = applySort(mangaMap)
|
||||||
libraryItems = mangaMap
|
sectionLibrary(mangaMap)
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view.onNextLibraryUpdate(libraryItems)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,10 +535,7 @@ class LibraryPresenter(
|
|||||||
allLibraryItems = mangaMap
|
allLibraryItems = mangaMap
|
||||||
val current = libraryItems
|
val current = libraryItems
|
||||||
setDownloadCount(current)
|
setDownloadCount(current)
|
||||||
libraryItems = current
|
sectionLibrary(current)
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view.onNextLibraryUpdate(libraryItems)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,10 +547,7 @@ class LibraryPresenter(
|
|||||||
allLibraryItems = mangaMap
|
allLibraryItems = mangaMap
|
||||||
val current = libraryItems
|
val current = libraryItems
|
||||||
setUnreadBadge(current)
|
setUnreadBadge(current)
|
||||||
libraryItems = current
|
sectionLibrary(current)
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view.onNextLibraryUpdate(libraryItems)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,10 +556,7 @@ class LibraryPresenter(
|
|||||||
scope.launch {
|
scope.launch {
|
||||||
var mangaMap = libraryItems
|
var mangaMap = libraryItems
|
||||||
mangaMap = applySort(mangaMap)
|
mangaMap = applySort(mangaMap)
|
||||||
libraryItems = mangaMap
|
sectionLibrary(mangaMap)
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
view.onNextLibraryUpdate(libraryItems)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.library.category
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.mikepenz.fastadapter.FastAdapter
|
||||||
|
import com.mikepenz.fastadapter.items.AbstractItem
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
|
|
||||||
|
class CategoryItem(val category: Category) :
|
||||||
|
AbstractItem<CategoryItem.ViewHolder>() {
|
||||||
|
|
||||||
|
/** defines the type defining this item. must be unique. preferably an id */
|
||||||
|
override val type: Int = R.id.category_text
|
||||||
|
|
||||||
|
/** defines the layout which will be used for this item in the list */
|
||||||
|
override val layoutRes: Int = R.layout.catergory_text_view
|
||||||
|
|
||||||
|
override var identifier = category.id?.toLong() ?: -1L
|
||||||
|
|
||||||
|
override fun getViewHolder(v: View): ViewHolder {
|
||||||
|
return ViewHolder(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View) : FastAdapter.ViewHolder<CategoryItem>(view) {
|
||||||
|
val categoryTitle: TextView = view.findViewById(R.id.category_text)
|
||||||
|
|
||||||
|
override fun bindView(item: CategoryItem, payloads: List<Any>) {
|
||||||
|
categoryTitle.text = item.category.name
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unbindView(item: CategoryItem) {
|
||||||
|
categoryTitle.text = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package eu.kanade.tachiyomi.ui.library.category
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.mikepenz.fastadapter.FastAdapter
|
||||||
|
import com.mikepenz.fastadapter.adapters.ItemAdapter
|
||||||
|
import com.mikepenz.fastadapter.listeners.OnBindViewHolderListenerImpl
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
|
import eu.kanade.tachiyomi.util.view.marginBottom
|
||||||
|
import eu.kanade.tachiyomi.util.view.marginTop
|
||||||
|
|
||||||
|
class CategoryRecyclerView @JvmOverloads constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null
|
||||||
|
) : RecyclerView(context, attrs) {
|
||||||
|
|
||||||
|
val manager = LinearLayoutManager(context)
|
||||||
|
private val fastAdapter: FastAdapter<CategoryItem>
|
||||||
|
var onCategoryClicked: (Int) -> Unit = { _ -> }
|
||||||
|
private val itemAdapter = ItemAdapter<CategoryItem>()
|
||||||
|
var selectedCategory: Int = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
fastAdapter = FastAdapter.with(itemAdapter)
|
||||||
|
layoutManager = manager
|
||||||
|
adapter = fastAdapter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCategories(items: List<Category>) {
|
||||||
|
itemAdapter.set(items.map(::CategoryItem))
|
||||||
|
fastAdapter.onBindViewHolderListener = (object : OnBindViewHolderListenerImpl<CategoryItem>() {
|
||||||
|
override fun onBindViewHolder(
|
||||||
|
viewHolder: ViewHolder,
|
||||||
|
position: Int,
|
||||||
|
payloads: List<Any>
|
||||||
|
) {
|
||||||
|
super.onBindViewHolder(viewHolder, position, payloads)
|
||||||
|
(viewHolder as? CategoryItem.ViewHolder)?.categoryTitle?.isSelected =
|
||||||
|
selectedCategory == position
|
||||||
|
}
|
||||||
|
})
|
||||||
|
fastAdapter.onClickListener = { _, _, item, _ ->
|
||||||
|
onCategoryClicked(item.category.order)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCategories(selected: Int) {
|
||||||
|
selectedCategory = selected
|
||||||
|
for (i in 0..manager.itemCount) {
|
||||||
|
(findViewHolderForAdapterPosition(i) as? CategoryItem.ViewHolder)?.categoryTitle?.isSelected =
|
||||||
|
selectedCategory == i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||||
|
val recyclerView = (parent.parent as ViewGroup).findViewById<RecyclerView>(R.id.recycler)
|
||||||
|
val top = recyclerView.marginTop
|
||||||
|
val bottom = recyclerView.marginBottom
|
||||||
|
val parent = recyclerView.measuredHeight - top - bottom
|
||||||
|
val heightS = if (parent > 0)
|
||||||
|
MeasureSpec.makeMeasureSpec(parent, MeasureSpec.AT_MOST)
|
||||||
|
else heightSpec
|
||||||
|
super.onMeasure(widthSpec, heightS)
|
||||||
|
}
|
||||||
|
}
|
5
app/src/main/res/drawable/ic_arrow_drop_down_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_arrow_drop_down_24dp.xml
Normal 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="M7,10l5,5 5,-5z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_arrow_drop_up_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_arrow_drop_up_24dp.xml
Normal 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="M7,14l5,-5 5,5z"/>
|
||||||
|
</vector>
|
@ -15,7 +15,7 @@
|
|||||||
</item>
|
</item>
|
||||||
|
|
||||||
<item android:id="@android:id/mask">
|
<item android:id="@android:id/mask">
|
||||||
<color android:color="@android:color/transparent" />
|
<color android:color="?android:colorBackground" />
|
||||||
</item>
|
</item>
|
||||||
</selector>
|
</selector>
|
||||||
</item>
|
</item>
|
||||||
|
20
app/src/main/res/layout/catergory_text_view.xml
Normal file
20
app/src/main/res/layout/catergory_text_view.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:background="@drawable/list_item_selector">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/category_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/list_item_selector"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
tools:text="@string/categories"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</FrameLayout>
|
@ -8,6 +8,14 @@
|
|||||||
android:background="@drawable/list_item_selector"
|
android:background="@drawable/list_item_selector"
|
||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:id="@+id/start_space"
|
||||||
|
android:layout_width="6dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/category_title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/category_title"
|
||||||
|
android:layout_height="1dp"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/checkbox"
|
android:id="@+id/checkbox"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -42,7 +50,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:barrierDirection="right"
|
app:barrierDirection="right"
|
||||||
app:constraint_referenced_ids="collapse_arrow,checkbox"
|
app:constraint_referenced_ids="start_space,collapse_arrow,checkbox"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -7,4 +7,5 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:columnWidth="140dp"
|
android:columnWidth="140dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
tools:listitem="@layout/manga_grid_item" />
|
android:background="@drawable/bottom_sheet_rounded_background"
|
||||||
|
tools:listitem="@layout/manga_grid_item"/>
|
||||||
|
@ -22,8 +22,37 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/category_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginTop="?actionBarSize"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="top"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
<com.google.android.material.checkbox.MaterialCheckBox
|
||||||
|
android:id="@+id/show_all"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/show_all"/>
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.ui.library.category.CategoryRecyclerView
|
||||||
|
android:id="@+id/category_recycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<include layout="@layout/library_grid_recycler" />
|
<include layout="@layout/library_grid_recycler" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/recycler_cover"
|
||||||
|
android:layout_marginTop="?actionBarSize"
|
||||||
|
android:alpha="0"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?android:colorBackground"/>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
@ -55,6 +55,16 @@
|
|||||||
android:textColor="?actionBarTintColor"
|
android:textColor="?actionBarTintColor"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
tools:text="Title Text" />
|
tools:text="Title Text" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dropdown"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:src="@drawable/ic_arrow_drop_down_24dp"
|
||||||
|
android:tint="?actionBarTintColor" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</eu.kanade.tachiyomi.ui.base.CenteredToolbar>
|
</eu.kanade.tachiyomi.ui.base.CenteredToolbar>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/manga_layout"
|
android:id="@+id/manga_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
tools:background="?android:attr/colorBackground"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom">
|
android:layout_gravity="bottom">
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@
|
|||||||
android:columnWidth="120dp"
|
android:columnWidth="120dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
tools:listitem="@layout/manga_grid_item"
|
tools:listitem="@layout/manga_grid_item"
|
||||||
android:background="?android:colorBackground"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto" />
|
xmlns:app="http://schemas.android.com/apk/res-auto" />
|
Loading…
Reference in New Issue
Block a user