mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 21:01:51 +01:00
Cleaning the library controller + removing the side swipe
^Since the fast scroll exists now Root controlllers can all now swipe up from the bottom bar to expose sheet Added option to refresh tracking for a manga
This commit is contained in:
parent
83206ded5e
commit
651682df4a
@ -177,7 +177,7 @@ class PreferencesHelper(val context: Context) {
|
||||
|
||||
fun gridSize() = rxPrefs.getInteger(Keys.gridSize, 1)
|
||||
|
||||
fun autoHideSeeker() = rxPrefs.getBoolean("auto_hide_seeker", true)
|
||||
fun alwaysShowSeeker() = rxPrefs.getBoolean("always_show_seeker", false)
|
||||
|
||||
fun uniformGrid() = rxPrefs.getBoolean(Keys.uniformGrid, true)
|
||||
|
||||
|
@ -2,12 +2,8 @@ package eu.kanade.tachiyomi.ui.base
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import androidx.appcompat.graphics.drawable.DrawerArrowDrawable
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import kotlinx.android.synthetic.main.main_activity.view.*
|
||||
|
||||
class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
@ -44,20 +40,4 @@ class CenteredToolbar@JvmOverloads constructor(context: Context, attrs: Attribut
|
||||
super.setTitle(null)
|
||||
}
|
||||
}
|
||||
|
||||
fun showSpinner(): PopupMenu {
|
||||
val popupMenu = PopupMenu(context, title_layout, Gravity.CENTER)
|
||||
dropdown.visible()
|
||||
title_layout.setOnTouchListener(popupMenu.dragToOpenListener)
|
||||
title_layout.setOnClickListener {
|
||||
popupMenu.show()
|
||||
}
|
||||
return popupMenu
|
||||
}
|
||||
|
||||
fun removeSpinner() {
|
||||
dropdown.gone()
|
||||
title_layout.setOnTouchListener(null)
|
||||
title_layout.setOnClickListener(null)
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,6 @@ abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateContr
|
||||
val onRoot: Boolean
|
||||
get() = router.backstack.lastOrNull()?.controller() == this
|
||||
|
||||
open fun handleRootBack(): Boolean = false
|
||||
|
||||
open fun getTitle(): String? {
|
||||
return null
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController
|
||||
import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
|
||||
import eu.kanade.tachiyomi.ui.catalogue.latest.LatestUpdatesController
|
||||
import eu.kanade.tachiyomi.ui.extension.SettingsExtensionsController
|
||||
import eu.kanade.tachiyomi.ui.main.BottomSheetController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.main.RootSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController
|
||||
@ -55,7 +56,7 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
|
||||
FlexibleAdapter.OnItemClickListener,
|
||||
CatalogueAdapter.OnBrowseClickListener,
|
||||
RootSearchInterface,
|
||||
|
||||
BottomSheetController,
|
||||
CatalogueAdapter.OnLatestClickListener {
|
||||
|
||||
/**
|
||||
@ -180,11 +181,11 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
|
||||
}
|
||||
}
|
||||
|
||||
fun showExtensions() {
|
||||
override fun showSheet() {
|
||||
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
fun toggleExtensions() {
|
||||
override fun toggleSheet() {
|
||||
if (ext_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
} else {
|
||||
@ -192,7 +193,7 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleRootBack(): Boolean {
|
||||
override fun handleSheetBack(): Boolean {
|
||||
if (ext_bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
ext_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
return true
|
||||
|
@ -72,8 +72,7 @@ class DownloadBottomSheet @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
update()
|
||||
setBottomSheet()
|
||||
|
||||
setInformationView()
|
||||
if (sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED && sheetBehavior?.isHideable == true) sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ class DisplayBottomSheet(private val controller: LibraryController) : BottomShee
|
||||
uniform_grid.bindToPreference(preferences.uniformGrid()) {
|
||||
controller.reattachAdapter()
|
||||
}
|
||||
autohide_seeker.bindToPreference(preferences.autoHideSeeker()) {
|
||||
controller.updateAutoHideScrollbar(autohide_seeker.isChecked)
|
||||
autohide_seeker.bindToPreference(preferences.alwaysShowSeeker()) {
|
||||
controller.updateShowScrollbar(autohide_seeker.isChecked)
|
||||
}
|
||||
grid_size_toggle_group.bindToPreference(preferences.gridSize()) {
|
||||
controller.reattachAdapter()
|
||||
|
@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.util.lang.chop
|
||||
import eu.kanade.tachiyomi.util.lang.removeArticles
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.text.SimpleDateFormat
|
||||
@ -158,7 +157,9 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
||||
val preferences: PreferencesHelper by injectLazy()
|
||||
val db: DatabaseHelper by injectLazy()
|
||||
return when (val iFlexible: IFlexible<*>? = getItem(position)) {
|
||||
is LibraryHeaderItem -> iFlexible.category.name
|
||||
is LibraryHeaderItem ->
|
||||
if (!preferences.hideCategories().getOrDefault()) iFlexible.category.name
|
||||
else recyclerView.context.getString(R.string.top)
|
||||
is LibraryItem -> {
|
||||
when (preferences.librarySortingMode().getOrDefault()) {
|
||||
LibrarySort.DRAG_AND_DROP -> {
|
||||
@ -170,8 +171,7 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
||||
} else {
|
||||
val category = db.getCategoriesForManga(iFlexible.manga)
|
||||
.executeAsBlocking().firstOrNull()?.name
|
||||
category?.chop(10)
|
||||
?: recyclerView.context.getString(R.string.default_category)
|
||||
category ?: recyclerView.context.getString(R.string.default_columns)
|
||||
}
|
||||
}
|
||||
LibrarySort.LAST_READ -> {
|
||||
@ -265,6 +265,5 @@ class LibraryCategoryAdapter(val libraryListener: LibraryListener) :
|
||||
fun sortCategory(catId: Int, sortBy: Int)
|
||||
fun selectAll(position: Int)
|
||||
fun allSelected(position: Int): Boolean
|
||||
fun recyclerIsScrolling(): Boolean
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,14 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Rect
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewPropertyAnimator
|
||||
@ -53,10 +48,9 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.library.filter.FilterBottomSheet
|
||||
import eu.kanade.tachiyomi.ui.main.BottomSheetController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.main.OnTouchEventInterface
|
||||
import eu.kanade.tachiyomi.ui.main.RootSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.main.SwipeGestureInterface
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.design.PreMigrationController
|
||||
import eu.kanade.tachiyomi.ui.migration.manga.process.MigrationListController
|
||||
@ -81,11 +75,7 @@ import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Locale
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.math.sign
|
||||
|
||||
class LibraryController(
|
||||
bundle: Bundle? = null,
|
||||
@ -95,7 +85,7 @@ class LibraryController(
|
||||
ChangeMangaCategoriesDialog.Listener,
|
||||
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener,
|
||||
FlexibleAdapter.OnItemMoveListener, LibraryCategoryAdapter.LibraryListener,
|
||||
OnTouchEventInterface, SwipeGestureInterface,
|
||||
BottomSheetController,
|
||||
RootSearchInterface, LibraryServiceListener {
|
||||
|
||||
init {
|
||||
@ -133,14 +123,9 @@ class LibraryController(
|
||||
|
||||
private var lastClickPosition = -1
|
||||
|
||||
private var updateScroll = true
|
||||
|
||||
private var lastItemPosition: Int? = null
|
||||
private var lastItem: IFlexible<*>? = null
|
||||
|
||||
private var switchingCategories = false
|
||||
var scrollDistance = 0f
|
||||
|
||||
lateinit var presenter: LibraryPresenter
|
||||
private set
|
||||
|
||||
@ -148,23 +133,12 @@ class LibraryController(
|
||||
|
||||
var snack: Snackbar? = null
|
||||
|
||||
// Horizontal scroll values
|
||||
private var startPosX: Float? = null
|
||||
private var startPosY: Float? = null
|
||||
private var moved = false
|
||||
private var lockedRecycler = false
|
||||
private var lockedY = false
|
||||
private var nextCategory: Int? = null
|
||||
private var ogCategory: Int? = null
|
||||
private var prevCategory: Int? = null
|
||||
private val swipeDistance = 500f
|
||||
private var flinging = false
|
||||
private var isDragging = false
|
||||
private var scrollDistance = 0f
|
||||
private val scrollDistanceTilHidden = 1000.dpToPx
|
||||
|
||||
private var textAnim: ViewPropertyAnimator? = null
|
||||
private var scrollAnim: ViewPropertyAnimator? = null
|
||||
private var autoHideScroller: Boolean = preferences.autoHideSeeker().getOrDefault()
|
||||
private var alwaysShowScroller: Boolean = preferences.alwaysShowSeeker().getOrDefault()
|
||||
|
||||
override fun getTitle(): String? {
|
||||
return if (view != null && presenter.categories.size > 1) presenter.categories.find {
|
||||
@ -193,7 +167,7 @@ class LibraryController(
|
||||
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
if (!autoHideScroller) return
|
||||
if (alwaysShowScroller) return
|
||||
when (newState) {
|
||||
RecyclerView.SCROLL_STATE_DRAGGING -> {
|
||||
scrollAnim?.cancel()
|
||||
@ -212,24 +186,23 @@ class LibraryController(
|
||||
}
|
||||
|
||||
private fun hideScroller() {
|
||||
if (!autoHideScroller) return
|
||||
scrollAnim = fast_scroller.animate()
|
||||
.setStartDelay(1000)
|
||||
.setDuration(250)
|
||||
.translationX(22f.dpToPx)
|
||||
if (alwaysShowScroller) return
|
||||
scrollAnim =
|
||||
fast_scroller.animate().setStartDelay(1000).setDuration(250).translationX(22f.dpToPx)
|
||||
scrollAnim?.start()
|
||||
}
|
||||
|
||||
private fun setFastScrollBackground() {
|
||||
val context = activity ?: return
|
||||
fast_scroller.background = if (autoHideScroller) ContextCompat.getDrawable(
|
||||
fast_scroller.background = if (!alwaysShowScroller) ContextCompat.getDrawable(
|
||||
context, R.drawable.fast_scroll_background
|
||||
) else null
|
||||
fast_scroller.textColor = ColorStateList.valueOf(
|
||||
context.getResourceColor(
|
||||
if (autoHideScroller) android.R.attr.textColorPrimaryInverse else android.R.attr.textColorPrimary
|
||||
if (!alwaysShowScroller) android.R.attr.textColorPrimaryInverse else android.R.attr.textColorPrimary
|
||||
)
|
||||
)
|
||||
fast_scroller.iconColor = fast_scroller.textColor
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View) {
|
||||
@ -252,15 +225,15 @@ class LibraryController(
|
||||
})
|
||||
recycler.setHasFixedSize(true)
|
||||
recycler.adapter = adapter
|
||||
fast_scroller.setupWithRecyclerView(
|
||||
recycler, { position ->
|
||||
val letter = adapter.getSectionText(position)
|
||||
if (!singleCategory && !adapter.isHeader(adapter.getItem(position))) null
|
||||
else if (letter != null) FastScrollItemIndicator.Text(letter)
|
||||
else FastScrollItemIndicator.Icon(R.drawable.star)
|
||||
})
|
||||
fast_scroller.setupWithRecyclerView(recycler, { position ->
|
||||
val letter = adapter.getSectionText(position)
|
||||
if (!singleCategory && !adapter.isHeader(adapter.getItem(position))) null
|
||||
else if (letter != null) FastScrollItemIndicator.Text(letter)
|
||||
else FastScrollItemIndicator.Icon(R.drawable.star)
|
||||
})
|
||||
fast_scroller.useDefaultScroller = false
|
||||
fast_scroller.itemIndicatorSelectedCallbacks += object : FastScrollerView.ItemIndicatorSelectedCallback {
|
||||
fast_scroller.itemIndicatorSelectedCallbacks += object :
|
||||
FastScrollerView.ItemIndicatorSelectedCallback {
|
||||
override fun onItemIndicatorSelected(
|
||||
indicator: FastScrollItemIndicator,
|
||||
indicatorCenterY: Int,
|
||||
@ -271,17 +244,21 @@ class LibraryController(
|
||||
|
||||
textAnim?.cancel()
|
||||
textAnim = text_view_m.animate().alpha(0f).setDuration(250L).setStartDelay(1000)
|
||||
textAnim?.start()
|
||||
this@LibraryController.view?.post {
|
||||
textAnim?.start()
|
||||
}
|
||||
|
||||
text_view_m.translationY = indicatorCenterY.toFloat() - text_view_m.height / 2
|
||||
text_view_m.alpha = 1f
|
||||
text_view_m.text = adapter.onCreateBubbleText(itemPosition)
|
||||
val appbar = activity?.appbar
|
||||
appbar?.y = 0f
|
||||
recycler.suppressLayout(true)
|
||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||
itemPosition,
|
||||
if (singleCategory) 0 else (if (itemPosition == 0) 0 else (-40).dpToPx)
|
||||
)
|
||||
recycler.suppressLayout(false)
|
||||
}
|
||||
}
|
||||
recycler.addOnScrollListener(scrollListener)
|
||||
@ -295,7 +272,6 @@ class LibraryController(
|
||||
}
|
||||
}
|
||||
|
||||
swipe_refresh.setDistanceToTriggerSync(150.dpToPx)
|
||||
swipe_refresh.setOnRefreshListener {
|
||||
swipe_refresh.isRefreshing = false
|
||||
if (!LibraryUpdateService.isRunning()) {
|
||||
@ -316,9 +292,7 @@ class LibraryController(
|
||||
0 -> updateLibrary(presenter.allCategories.first())
|
||||
else -> updateLibrary()
|
||||
}
|
||||
})
|
||||
.positiveButton(R.string.action_update)
|
||||
.show()
|
||||
}).positiveButton(R.string.action_update).show()
|
||||
}
|
||||
else -> {
|
||||
when (preferences.updateOnRefresh().getOrDefault()) {
|
||||
@ -360,110 +334,6 @@ class LibraryController(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent?) {
|
||||
if (event == null) {
|
||||
resetScrollingValues()
|
||||
resetRecyclerY()
|
||||
return
|
||||
}
|
||||
if (flinging || presenter.categories.size <= 1) return
|
||||
if (isDragging) {
|
||||
resetScrollingValues()
|
||||
resetRecyclerY(false)
|
||||
return
|
||||
}
|
||||
val sheetRect = Rect()
|
||||
val recyclerRect = Rect()
|
||||
val appBarRect = Rect()
|
||||
bottom_sheet.getGlobalVisibleRect(sheetRect)
|
||||
view?.getGlobalVisibleRect(recyclerRect)
|
||||
activity?.appbar?.getGlobalVisibleRect(appBarRect)
|
||||
|
||||
if (startPosX == null) {
|
||||
startPosX = event.rawX
|
||||
startPosY = event.rawY
|
||||
val position =
|
||||
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
||||
val order = activeCategory
|
||||
ogCategory = order
|
||||
var newOffsetN = order + 1
|
||||
while (adapter.indexOf(newOffsetN) == -1 && presenter.categories.any { it.order == newOffsetN }) {
|
||||
newOffsetN += 1
|
||||
}
|
||||
if (adapter.indexOf(newOffsetN) != -1) nextCategory = newOffsetN
|
||||
|
||||
if (position == 0) prevCategory = null
|
||||
else {
|
||||
var newOffsetP = order - 1
|
||||
while (adapter.indexOf(newOffsetP) == -1 && presenter.categories.any { it.order == newOffsetP }) {
|
||||
newOffsetP -= 1
|
||||
}
|
||||
if (adapter.indexOf(newOffsetP) != -1) prevCategory = newOffsetP
|
||||
}
|
||||
return
|
||||
}
|
||||
if (event.actionMasked == MotionEvent.ACTION_UP) {
|
||||
recycler_layout.post {
|
||||
if (!flinging) {
|
||||
resetScrollingValues()
|
||||
resetRecyclerY(true)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (startPosX != null && startPosY != null && (sheetRect.contains(
|
||||
startPosX!!.toInt(),
|
||||
startPosY!!.toInt()
|
||||
) || !recyclerRect.contains(
|
||||
startPosX!!.toInt(),
|
||||
startPosY!!.toInt()
|
||||
) || appBarRect.contains(startPosX!!.toInt(), startPosY!!.toInt()))
|
||||
) {
|
||||
return
|
||||
}
|
||||
if (event.actionMasked != MotionEvent.ACTION_UP && startPosX != null) {
|
||||
val distance = abs(event.rawX - startPosX!!)
|
||||
val sign = sign(event.rawX - startPosX!!)
|
||||
|
||||
if (lockedY) return
|
||||
|
||||
if (distance > 60 && abs(event.rawY - startPosY!!) <= 30 && !lockedRecycler) {
|
||||
swipe_refresh.isEnabled = false
|
||||
lockedRecycler = true
|
||||
switchingCategories = true
|
||||
recycler.suppressLayout(true)
|
||||
} else if (!lockedRecycler && abs(event.rawY - startPosY!!) > 30) {
|
||||
lockedY = true
|
||||
resetRecyclerY()
|
||||
return
|
||||
}
|
||||
if (abs(event.rawY - startPosY!!) <= 30 || recycler.isLayoutSuppressed || lockedRecycler) {
|
||||
|
||||
if ((prevCategory == null && sign > 0) || (nextCategory == null && sign < 0)) {
|
||||
recycler_layout.x = sign * distance.pow(0.6f)
|
||||
recycler_layout.alpha = 1f
|
||||
} else if (distance <= swipeDistance * 1.1f) {
|
||||
recycler_layout.x = sign * (distance / (swipeDistance / 3f)).pow(3.5f)
|
||||
recycler_layout.alpha =
|
||||
(1f - (distance - (swipeDistance * 0.1f)) / swipeDistance)
|
||||
if (moved) {
|
||||
scrollToHeader(ogCategory ?: -1)
|
||||
moved = false
|
||||
}
|
||||
} else {
|
||||
if (!moved) {
|
||||
scrollToHeader((if (sign <= 0) nextCategory else prevCategory) ?: -1)
|
||||
moved = true
|
||||
}
|
||||
recycler_layout.x = -sign * (max(0f, (swipeDistance * 2 - distance)) /
|
||||
(swipeDistance / 3f)).pow(3.5f)
|
||||
recycler_layout.alpha = ((distance - swipeDistance * 1.1f) / swipeDistance)
|
||||
recycler_layout.alpha = min(1f, recycler_layout.alpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCategoryOrder(): Int? {
|
||||
val position =
|
||||
(recycler.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
|
||||
@ -484,57 +354,16 @@ class LibraryController(
|
||||
return order
|
||||
}
|
||||
|
||||
private fun resetScrollingValues() {
|
||||
swipe_refresh.isEnabled = !isDragging
|
||||
startPosX = null
|
||||
startPosY = null
|
||||
nextCategory = null
|
||||
prevCategory = null
|
||||
ogCategory = null
|
||||
lockedY = false
|
||||
}
|
||||
|
||||
fun updateAutoHideScrollbar(autoHide: Boolean) {
|
||||
autoHideScroller = autoHide
|
||||
fun updateShowScrollbar(show: Boolean) {
|
||||
alwaysShowScroller = show
|
||||
setFastScrollBackground()
|
||||
if (libraryLayout == 0) reattachAdapter()
|
||||
scrollAnim?.cancel()
|
||||
if (autoHide) hideScroller()
|
||||
else fast_scroller.translationX = 0f
|
||||
if (show) fast_scroller.translationX = 0f
|
||||
else hideScroller()
|
||||
setRecyclerLayout()
|
||||
}
|
||||
|
||||
private fun resetRecyclerY(animated: Boolean = false, time: Long = 100) {
|
||||
swipe_refresh.isEnabled = !isDragging
|
||||
moved = false
|
||||
lockedRecycler = false
|
||||
if (animated) {
|
||||
val set = AnimatorSet()
|
||||
val translationXAnimator = ValueAnimator.ofFloat(recycler_layout.x, 0f)
|
||||
translationXAnimator.duration = time
|
||||
translationXAnimator.addUpdateListener { animation ->
|
||||
recycler_layout.x = animation.animatedValue as Float
|
||||
}
|
||||
|
||||
val translationAlphaAnimator = ValueAnimator.ofFloat(recycler_layout.alpha, 1f)
|
||||
translationAlphaAnimator.duration = time
|
||||
translationAlphaAnimator.addUpdateListener { animation ->
|
||||
recycler_layout.alpha = animation.animatedValue as Float
|
||||
}
|
||||
set.playTogether(translationXAnimator, translationAlphaAnimator)
|
||||
set.start()
|
||||
|
||||
launchUI {
|
||||
delay(time)
|
||||
if (!lockedRecycler) switchingCategories = false
|
||||
}
|
||||
} else {
|
||||
recycler_layout.x = 0f
|
||||
recycler_layout.alpha = 1f
|
||||
switchingCategories = false
|
||||
}
|
||||
recycler.suppressLayout(false)
|
||||
}
|
||||
|
||||
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
||||
return inflater.inflate(R.layout.library_list_controller, container, false)
|
||||
}
|
||||
@ -550,12 +379,15 @@ class LibraryController(
|
||||
private fun setRecyclerLayout() {
|
||||
if (libraryLayout == 0) {
|
||||
recycler.spanCount = 1
|
||||
recycler.updatePaddingRelative(start = 0, end = if (!autoHideScroller) 10.dpToPx else 0)
|
||||
recycler.updatePaddingRelative(
|
||||
start = 0,
|
||||
end = 0
|
||||
)
|
||||
} else {
|
||||
recycler.columnWidth = (90 + (preferences.gridSize().getOrDefault() * 30)).dpToPx
|
||||
recycler.updatePaddingRelative(
|
||||
start = (if (!autoHideScroller) 2 else 5).dpToPx,
|
||||
end = (if (!autoHideScroller) 12 else 5).dpToPx
|
||||
start = (if (alwaysShowScroller) 2 else 5).dpToPx,
|
||||
end = (if (alwaysShowScroller) 12 else 5).dpToPx
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -563,11 +395,6 @@ class LibraryController(
|
||||
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
|
||||
super.onChangeStarted(handler, type)
|
||||
if (type.isEnter) {
|
||||
/*if (presenter.categories.size > 1) {
|
||||
activity?.toolbar?.showSpinner()
|
||||
} else {
|
||||
activity?.toolbar?.removeSpinner()
|
||||
}*/
|
||||
presenter.getLibrary()
|
||||
DownloadService.callListeners()
|
||||
LibraryUpdateService.setListener(this)
|
||||
@ -581,8 +408,6 @@ class LibraryController(
|
||||
if (observeLater && ::presenter.isInitialized) {
|
||||
presenter.getLibrary()
|
||||
}
|
||||
resetScrollingValues()
|
||||
resetRecyclerY()
|
||||
}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
@ -617,62 +442,32 @@ class LibraryController(
|
||||
adapter.setItems(mangaMap)
|
||||
singleCategory = presenter.categories.size <= 1
|
||||
|
||||
fast_scroller.translationX = 0f
|
||||
hideScroller()
|
||||
|
||||
setTitle()
|
||||
updateScroll = false
|
||||
if (!freshStart) {
|
||||
justStarted = false
|
||||
if (recycler_layout.alpha == 0f) recycler_layout.animate().alpha(1f).setDuration(500)
|
||||
.start()
|
||||
} else if (justStarted) {
|
||||
if (freshStart) scrollToHeader(activeCategory)
|
||||
} else {
|
||||
updateScroll = true
|
||||
} else if (justStarted && freshStart) {
|
||||
scrollToHeader(activeCategory)
|
||||
fast_scroller.translationX = 0f
|
||||
hideScroller()
|
||||
}
|
||||
adapter.isLongPressDragEnabled = canDrag()
|
||||
|
||||
/*val popupMenu = if (presenter.categories.size > 1 && isCurrentController) {
|
||||
activity?.toolbar?.showSpinner()
|
||||
} else {
|
||||
activity?.toolbar?.removeSpinner()
|
||||
null
|
||||
}*/
|
||||
|
||||
/*presenter.categories.forEach { category ->
|
||||
popupMenu?.menu?.add(0, category.order, max(0, category.order), category.name)
|
||||
}
|
||||
|
||||
popupMenu?.setOnMenuItemClickListener { item ->
|
||||
scrollToHeader(item.itemId)
|
||||
true
|
||||
}*/
|
||||
}
|
||||
|
||||
private fun scrollToHeader(pos: Int) {
|
||||
val headerPosition = adapter.indexOf(pos)
|
||||
switchingCategories = true
|
||||
if (headerPosition > -1) {
|
||||
val appbar = activity?.appbar
|
||||
recycler.suppressLayout(true)
|
||||
val appbarOffset = if (appbar?.y ?: 0f > -20) 0 else (appbar?.y?.plus(
|
||||
view?.rootWindowInsets?.systemWindowInsetTop ?: 0
|
||||
) ?: 0f).roundToInt() + 30.dpToPx
|
||||
view?.rootWindowInsets?.systemWindowInsetTop ?: 0
|
||||
) ?: 0f).roundToInt() + 30.dpToPx
|
||||
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
||||
headerPosition, (if (headerPosition == 0) 0 else (-40).dpToPx) + appbarOffset
|
||||
)
|
||||
|
||||
/*val headerItem = adapter.getItem(headerPosition) as? LibraryHeaderItem
|
||||
if (headerItem != null) {
|
||||
setTitle()
|
||||
}*/
|
||||
recycler.suppressLayout(false)
|
||||
}
|
||||
launchUI {
|
||||
delay(100)
|
||||
switchingCategories = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun onRefresh() {
|
||||
@ -763,13 +558,16 @@ class LibraryController(
|
||||
}
|
||||
|
||||
override fun startReading(position: Int) {
|
||||
if (recyclerIsScrolling()) return
|
||||
if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
||||
toggleSelection(position)
|
||||
return
|
||||
}
|
||||
val manga = (adapter.getItem(position) as? LibraryItem)?.manga ?: return
|
||||
startReading(manga)
|
||||
val activity = activity ?: return
|
||||
val chapter = presenter.getFirstUnread(manga) ?: return
|
||||
val intent = ReaderActivity.newIntent(activity, manga, chapter)
|
||||
destroyActionModeIfNeeded()
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun toggleSelection(position: Int) {
|
||||
@ -792,7 +590,6 @@ class LibraryController(
|
||||
* @return true if the item should be selected, false otherwise.
|
||||
*/
|
||||
override fun onItemClick(view: View?, position: Int): Boolean {
|
||||
if (recyclerIsScrolling()) return false
|
||||
val item = adapter.getItem(position) as? LibraryItem ?: return false
|
||||
return if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
||||
lastClickPosition = position
|
||||
@ -804,9 +601,11 @@ class LibraryController(
|
||||
}
|
||||
}
|
||||
|
||||
private fun openManga(manga: Manga) = router.pushController(MangaDetailsController(
|
||||
manga
|
||||
).withFadeTransaction())
|
||||
private fun openManga(manga: Manga) = router.pushController(
|
||||
MangaDetailsController(
|
||||
manga
|
||||
).withFadeTransaction()
|
||||
)
|
||||
|
||||
/**
|
||||
* Called when a manga is long clicked.
|
||||
@ -814,7 +613,6 @@ class LibraryController(
|
||||
* @param position the position of the element clicked.
|
||||
*/
|
||||
override fun onItemLongClick(position: Int) {
|
||||
if (recyclerIsScrolling()) return
|
||||
if (adapter.getItem(position) is LibraryHeaderItem) return
|
||||
createActionModeIfNeeded()
|
||||
when {
|
||||
@ -834,7 +632,6 @@ class LibraryController(
|
||||
val position = viewHolder?.adapterPosition ?: return
|
||||
swipe_refresh.isEnabled = actionState != ItemTouchHelper.ACTION_STATE_DRAG
|
||||
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
|
||||
isDragging = true
|
||||
activity?.appbar?.y = 0f
|
||||
if (lastItemPosition != null && position != lastItemPosition && lastItem == adapter.getItem(
|
||||
position
|
||||
@ -875,27 +672,17 @@ class LibraryController(
|
||||
else if (lastItemPosition == null) lastItemPosition = fromPosition
|
||||
}
|
||||
|
||||
fun toggleFilters() {
|
||||
if (bottom_sheet.sheetBehavior?.isHideable == true && bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) bottom_sheet.sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_HIDDEN
|
||||
else if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_COLLAPSED && bottom_sheet.sheetBehavior?.skipCollapsed == false) bottom_sheet.sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_COLLAPSED
|
||||
else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
override fun shouldMoveItem(fromPosition: Int, toPosition: Int): Boolean {
|
||||
if (adapter.isSelected(fromPosition)) toggleSelection(fromPosition)
|
||||
val item = adapter.getItem(fromPosition) as? LibraryItem ?: return false
|
||||
val newHeader = adapter.getSectionHeader(toPosition) as? LibraryHeaderItem
|
||||
if (toPosition <= 1) return false
|
||||
return (adapter.getItem(toPosition) !is LibraryHeaderItem) && (newHeader?.category?.id == item.manga.category || !presenter.mangaIsInCategory(
|
||||
item.manga,
|
||||
newHeader?.category?.id
|
||||
item.manga, newHeader?.category?.id
|
||||
))
|
||||
}
|
||||
|
||||
override fun onItemReleased(position: Int) {
|
||||
isDragging = false
|
||||
if (adapter.selectedItemCount > 0) {
|
||||
lastItemPosition = null
|
||||
return
|
||||
@ -1009,66 +796,25 @@ class LibraryController(
|
||||
return items.all { adapter.isSelected(it) }
|
||||
}
|
||||
|
||||
override fun onSwipeBottom(x: Float, y: Float) {}
|
||||
override fun onSwipeTop(x: Float, y: Float) {
|
||||
val sheetRect = Rect()
|
||||
activity!!.bottom_nav.getGlobalVisibleRect(sheetRect)
|
||||
if (sheetRect.contains(x.toInt(), y.toInt())) {
|
||||
if (bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED) toggleFilters()
|
||||
override fun showSheet() {
|
||||
if (bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_HIDDEN) bottom_sheet.sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_COLLAPSED
|
||||
else bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
override fun toggleSheet() {
|
||||
when {
|
||||
bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_HIDDEN -> bottom_sheet.sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_COLLAPSED
|
||||
bottom_sheet.sheetBehavior?.state != BottomSheetBehavior.STATE_EXPANDED -> bottom_sheet.sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_EXPANDED
|
||||
bottom_sheet.sheetBehavior?.isHideable == true -> bottom_sheet.sheetBehavior?.state =
|
||||
BottomSheetBehavior.STATE_HIDDEN
|
||||
else -> bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSwipeLeft(x: Float, xPos: Float) = goToNextCategory(x, xPos)
|
||||
override fun onSwipeRight(x: Float, xPos: Float) = goToNextCategory(x, xPos)
|
||||
|
||||
private fun goToNextCategory(x: Float, xPos: Float) {
|
||||
if (lockedRecycler && abs(x) > 1000f) {
|
||||
val sign = sign(x).roundToInt()
|
||||
if ((sign < 0 && nextCategory == null) || (sign > 0) && prevCategory == null) return
|
||||
val distance = recycler_layout.alpha
|
||||
val speed = max(5000f / abs(x), 0.75f)
|
||||
if (sign(recycler_layout.x) == sign(x)) {
|
||||
flinging = true
|
||||
val duration = (distance * 100 * speed).toLong()
|
||||
val set = AnimatorSet()
|
||||
val translationXAnimator = ValueAnimator.ofFloat(abs(xPos - startPosX!!),
|
||||
swipeDistance)
|
||||
translationXAnimator.duration = duration
|
||||
translationXAnimator.addUpdateListener { animation ->
|
||||
recycler_layout.x = sign *
|
||||
(animation.animatedValue as Float / (swipeDistance / 3f)).pow(3.5f)
|
||||
}
|
||||
|
||||
val translationAlphaAnimator = ValueAnimator.ofFloat(recycler_layout.alpha, 0f)
|
||||
translationAlphaAnimator.duration = duration
|
||||
translationAlphaAnimator.addUpdateListener { animation ->
|
||||
recycler_layout.alpha = animation.animatedValue as Float
|
||||
}
|
||||
set.playTogether(translationXAnimator, translationAlphaAnimator)
|
||||
set.start()
|
||||
set.addListener(object : Animator.AnimatorListener {
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
recycler_layout.x = -sign * (swipeDistance / (swipeDistance / 3f)).pow(3.5f)
|
||||
recycler_layout.alpha = 0f
|
||||
recycler_layout.post {
|
||||
scrollToHeader((if (sign <= 0) nextCategory else prevCategory) ?: -1)
|
||||
recycler_layout.post {
|
||||
resetScrollingValues()
|
||||
resetRecyclerY(true, (100 * speed).toLong())
|
||||
flinging = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAnimationCancel(animation: Animator?) {}
|
||||
override fun onAnimationRepeat(animation: Animator?) {}
|
||||
override fun onAnimationStart(animation: Animator?) {}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleRootBack(): Boolean {
|
||||
override fun handleSheetBack(): Boolean {
|
||||
val sheetBehavior = BottomSheetBehavior.from(bottom_sheet)
|
||||
if (sheetBehavior.state != BottomSheetBehavior.STATE_COLLAPSED && sheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) {
|
||||
sheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
@ -1131,7 +877,7 @@ class LibraryController(
|
||||
/**
|
||||
* Invalidates the action mode, forcing it to refresh its content.
|
||||
*/
|
||||
fun invalidateActionMode() {
|
||||
private fun invalidateActionMode() {
|
||||
actionMode?.invalidate()
|
||||
}
|
||||
|
||||
@ -1214,15 +960,6 @@ class LibraryController(
|
||||
destroyActionModeIfNeeded()
|
||||
}
|
||||
|
||||
// / Method for the category view
|
||||
private fun startReading(manga: Manga) {
|
||||
val activity = activity ?: return
|
||||
val chapter = presenter.getFirstUnread(manga) ?: return
|
||||
val intent = ReaderActivity.newIntent(activity, manga, chapter)
|
||||
destroyActionModeIfNeeded()
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the selected manga to a list of categories.
|
||||
*/
|
||||
@ -1241,6 +978,4 @@ class LibraryController(
|
||||
router
|
||||
)
|
||||
}
|
||||
|
||||
override fun recyclerIsScrolling() = switchingCategories || lockedRecycler || lockedY
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
@ -9,6 +10,7 @@ import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.f2prateek.rx.preferences.Preference
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.SelectableAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractHeaderItem
|
||||
@ -17,6 +19,7 @@ import eu.davidea.viewholders.FlexibleViewHolder
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
@ -24,7 +27,11 @@ import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import kotlinx.android.synthetic.main.library_category_header_item.view.*
|
||||
|
||||
class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int) :
|
||||
class LibraryHeaderItem(
|
||||
private val categoryF: (Int) -> Category,
|
||||
private val catId: Int,
|
||||
private val showFastScroll: Preference<Boolean>
|
||||
) :
|
||||
AbstractHeaderItem<LibraryHeaderItem.Holder>() {
|
||||
|
||||
override fun getLayoutRes(): Int {
|
||||
@ -35,7 +42,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
view: View,
|
||||
adapter: FlexibleAdapter<IFlexible<RecyclerView.ViewHolder>>
|
||||
): Holder {
|
||||
return Holder(view, adapter as LibraryCategoryAdapter)
|
||||
return Holder(view, adapter as LibraryCategoryAdapter, showFastScroll.getOrDefault())
|
||||
}
|
||||
|
||||
override fun bindViewHolder(
|
||||
@ -70,7 +77,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
return -(category.id!!)
|
||||
}
|
||||
|
||||
class Holder(val view: View, private val adapter: LibraryCategoryAdapter) :
|
||||
class Holder(val view: View, private val adapter: LibraryCategoryAdapter, padEnd: Boolean) :
|
||||
FlexibleViewHolder(view, adapter, true) {
|
||||
|
||||
private val sectionText: TextView = view.findViewById(R.id.category_title)
|
||||
@ -79,6 +86,9 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
private val checkboxImage: ImageView = view.findViewById(R.id.checkbox)
|
||||
|
||||
init {
|
||||
sortText.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
marginEnd = (if (padEnd && adapter.recyclerView.paddingEnd == 0) 12 else 2).dpToPx
|
||||
}
|
||||
updateButton.setOnClickListener { addCategoryToUpdate() }
|
||||
sortText.setOnClickListener { it.post { showCatSortOptions() } }
|
||||
checkboxImage.setOnClickListener { selectAll() }
|
||||
@ -140,7 +150,6 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int
|
||||
}
|
||||
}
|
||||
private fun showCatSortOptions() {
|
||||
if (adapter.libraryListener.recyclerIsScrolling()) return
|
||||
val category =
|
||||
(adapter.getItem(adapterPosition) as? LibraryHeaderItem)?.category ?: return
|
||||
// Create a PopupMenu, giving it the clicked view for an anchor
|
||||
|
@ -28,6 +28,7 @@ class LibraryItem(
|
||||
val manga: LibraryManga,
|
||||
private val libraryLayout: Preference<Int>,
|
||||
private val fixedSize: Preference<Boolean>,
|
||||
private val showFastScroll: Preference<Boolean>,
|
||||
header: LibraryHeaderItem?
|
||||
) :
|
||||
AbstractSectionableItem<LibraryHolder, LibraryHeaderItem?>(header), IFilterable<String> {
|
||||
@ -49,7 +50,7 @@ class LibraryItem(
|
||||
val libraryLayout = libraryLayout.getOrDefault()
|
||||
val isFixedSize = fixedSize.getOrDefault()
|
||||
if (libraryLayout == 0 || manga.isBlank()) {
|
||||
LibraryListHolder(view, adapter as LibraryCategoryAdapter)
|
||||
LibraryListHolder(view, adapter as LibraryCategoryAdapter, showFastScroll.getOrDefault())
|
||||
} else {
|
||||
view.apply {
|
||||
val coverHeight = (parent.itemWidth / 3f * 4f).toInt()
|
||||
@ -94,7 +95,7 @@ class LibraryItem(
|
||||
)
|
||||
}
|
||||
} else {
|
||||
LibraryListHolder(view, adapter as LibraryCategoryAdapter)
|
||||
LibraryListHolder(view, adapter as LibraryCategoryAdapter, showFastScroll.getOrDefault())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.signature.ObjectKey
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.view.gone
|
||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||
import eu.kanade.tachiyomi.util.view.visible
|
||||
import kotlinx.android.synthetic.main.catalogue_list_item.*
|
||||
import kotlinx.android.synthetic.main.catalogue_list_item.view.*
|
||||
@ -25,9 +28,16 @@ import kotlinx.android.synthetic.main.unread_download_badge.*
|
||||
|
||||
class LibraryListHolder(
|
||||
private val view: View,
|
||||
adapter: LibraryCategoryAdapter
|
||||
adapter: LibraryCategoryAdapter,
|
||||
padEnd: Boolean
|
||||
) : LibraryHolder(view, adapter) {
|
||||
|
||||
init {
|
||||
badge_view?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
marginEnd = (if (padEnd) 22 else 12).dpToPx
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this
|
||||
* holder with the given manga.
|
||||
|
@ -468,56 +468,43 @@ class LibraryPresenter(
|
||||
val showCategories = !preferences.hideCategories().getOrDefault()
|
||||
val unreadBadgeType = preferences.unreadBadgeType().getOrDefault()
|
||||
var libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||
val singleList = true
|
||||
val seekPref = preferences.alwaysShowSeeker()
|
||||
if (!showCategories)
|
||||
libraryManga = libraryManga.distinctBy { it.id }
|
||||
/*val libraryMap = libraryManga.map { manga ->
|
||||
LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType }
|
||||
}.groupBy {
|
||||
if (showCategories) it.manga.category else 0
|
||||
}*/
|
||||
val categoryAll = Category.createAll(context,
|
||||
preferences.librarySortingMode().getOrDefault(),
|
||||
preferences.librarySortingAscending().getOrDefault())
|
||||
val catItemAll = LibraryHeaderItem({ categoryAll }, -1)
|
||||
val catItemAll = LibraryHeaderItem({ categoryAll }, -1, seekPref)
|
||||
val libraryMap =
|
||||
if (!singleList) {
|
||||
libraryManga.map { manga ->
|
||||
LibraryItem(manga, libraryLayout, preferences.uniformGrid(), null).apply { unreadType =
|
||||
unreadBadgeType }
|
||||
}.groupBy {
|
||||
if (showCategories) it.manga.category else -1
|
||||
libraryManga.groupBy { manga ->
|
||||
if (showCategories) manga.category else -1
|
||||
// LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType }
|
||||
}.map { entry ->
|
||||
val categoryItem =
|
||||
if (!showCategories) catItemAll else
|
||||
(LibraryHeaderItem({ getCategory(it) }, entry.key, seekPref))
|
||||
entry.value.map {
|
||||
LibraryItem(
|
||||
it, libraryLayout, preferences.uniformGrid(), seekPref, categoryItem
|
||||
).apply { unreadType = unreadBadgeType }
|
||||
}
|
||||
} else {
|
||||
libraryManga.groupBy { manga ->
|
||||
if (showCategories) manga.category else -1
|
||||
// LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType }
|
||||
}.map { entry ->
|
||||
val categoryItem =
|
||||
if (!showCategories) catItemAll else
|
||||
(LibraryHeaderItem({ getCategory(it) }, entry.key))
|
||||
entry.value.map {
|
||||
LibraryItem(
|
||||
it, libraryLayout, preferences.uniformGrid(), categoryItem
|
||||
).apply { unreadType = unreadBadgeType }
|
||||
}
|
||||
}.map {
|
||||
val cat = if (showCategories) it.firstOrNull()?.manga?.category ?: 0 else -1
|
||||
cat to it
|
||||
// LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType }
|
||||
}.toMap()
|
||||
}.toMutableMap()
|
||||
}.map {
|
||||
val cat = if (showCategories) it.firstOrNull()?.manga?.category ?: 0 else -1
|
||||
cat to it
|
||||
// LibraryItem(manga, libraryLayout).apply { unreadType = unreadBadgeType }
|
||||
}.toMap().toMutableMap()
|
||||
|
||||
if (showCategories) {
|
||||
categories.forEach { category ->
|
||||
if (category.id ?: 0 <= 0 && !libraryMap.containsKey(category.id)) {
|
||||
val headerItem =
|
||||
LibraryHeaderItem({ getCategory(category.id!!) }, category.id!!)
|
||||
LibraryHeaderItem({ getCategory(category.id!!) }, category.id!!, seekPref)
|
||||
libraryMap[category.id!!] = listOf(
|
||||
LibraryItem(
|
||||
LibraryManga.createBlank(category.id!!),
|
||||
libraryLayout,
|
||||
preferences.uniformGrid(),
|
||||
preferences.alwaysShowSeeker(),
|
||||
headerItem
|
||||
)
|
||||
)
|
||||
|
@ -81,7 +81,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
private set
|
||||
private var searchDrawable: Drawable? = null
|
||||
private var dismissDrawable: Drawable? = null
|
||||
private var currentGestureDelegate: SwipeGestureInterface? = null
|
||||
private lateinit var gestureDetector: GestureDetectorCompat
|
||||
|
||||
private var snackBar: Snackbar? = null
|
||||
@ -156,23 +155,9 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
}, id)
|
||||
} else if (currentRoot.tag()?.toIntOrNull() == id) {
|
||||
if (router.backstackSize == 1) {
|
||||
when (id) {
|
||||
R.id.nav_recents -> {
|
||||
val controller =
|
||||
router.getControllerWithTag(id.toString()) as? RecentsController
|
||||
controller?.toggleDownloads()
|
||||
}
|
||||
R.id.nav_library -> {
|
||||
val controller =
|
||||
router.getControllerWithTag(id.toString()) as? LibraryController
|
||||
controller?.toggleFilters()
|
||||
}
|
||||
R.id.nav_catalogues -> {
|
||||
val controller =
|
||||
router.getControllerWithTag(id.toString()) as? CatalogueController
|
||||
controller?.toggleExtensions()
|
||||
}
|
||||
}
|
||||
val controller =
|
||||
router.getControllerWithTag(id.toString()) as? BottomSheetController
|
||||
controller?.toggleSheet()
|
||||
}
|
||||
}
|
||||
true
|
||||
@ -389,7 +374,7 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
bottom_nav.post {
|
||||
val controller =
|
||||
router.backstack.firstOrNull()?.controller() as? CatalogueController
|
||||
controller?.showExtensions()
|
||||
controller?.showSheet()
|
||||
}
|
||||
}
|
||||
SHORTCUT_MANGA -> {
|
||||
@ -398,12 +383,12 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
router.pushController(MangaDetailsController(extras).withFadeTransaction())
|
||||
}
|
||||
SHORTCUT_DOWNLOADS -> {
|
||||
bottom_nav.selectedItemId = R.id.nav_catalogues
|
||||
bottom_nav.selectedItemId = R.id.nav_recents
|
||||
router.popToRoot()
|
||||
bottom_nav.post {
|
||||
val controller =
|
||||
router.backstack.firstOrNull()?.controller() as? RecentsController
|
||||
controller?.showDownloads()
|
||||
controller?.showSheet()
|
||||
}
|
||||
}
|
||||
Intent.ACTION_SEARCH, "com.google.android.gms.actions.SEARCH_ACTION" -> {
|
||||
@ -446,21 +431,13 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
/*if (trulyGoBack) {
|
||||
super.onBackPressed()
|
||||
return
|
||||
}*/
|
||||
/*if (drawer.isDrawerOpen(GravityCompat.START) || drawer.isDrawerOpen(GravityCompat.END)) {
|
||||
drawer.closeDrawers()
|
||||
} else {*/
|
||||
val baseController = router.backstack.last().controller() as? BaseController
|
||||
if (if (router.backstackSize == 1) !(baseController?.handleRootBack() ?: false)
|
||||
val sheetController = router.backstack.last().controller() as? BottomSheetController
|
||||
if (if (router.backstackSize == 1) !(sheetController?.handleSheetBack() ?: false)
|
||||
else !router.handleBack()
|
||||
) {
|
||||
SecureActivityDelegate.locked = true
|
||||
super.onBackPressed()
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private fun setRoot(controller: Controller, id: Int) {
|
||||
@ -484,8 +461,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||
gestureDetector.onTouchEvent(ev)
|
||||
val controller = router.backstack.lastOrNull()?.controller()
|
||||
if (controller is OnTouchEventInterface) controller.onTouchEvent(ev)
|
||||
if (ev?.action == MotionEvent.ACTION_DOWN) {
|
||||
if (snackBar != null && snackBar!!.isShown) {
|
||||
val sRect = Rect()
|
||||
@ -530,10 +505,6 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
}
|
||||
drawerArrow?.progress = 1f
|
||||
|
||||
currentGestureDelegate = to as? SwipeGestureInterface
|
||||
|
||||
if (to !is SpinnerTitleInterface) toolbar.removeSpinner()
|
||||
|
||||
if (to !is DialogController) {
|
||||
bottom_nav.visibility =
|
||||
if (router.backstackSize == 0 || (router.backstackSize <= 1 && !isPush)) View.VISIBLE else bottom_nav.visibility
|
||||
@ -587,37 +558,21 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
||||
velocityX: Float,
|
||||
velocityY: Float
|
||||
): Boolean {
|
||||
if (currentGestureDelegate == null) return false
|
||||
var result = false
|
||||
try {
|
||||
val diffY = e2.y - e1.y
|
||||
val diffX = e2.x - e1.x
|
||||
if (abs(diffX) > abs(diffY)) {
|
||||
if (abs(diffX) > Companion.SWIPE_THRESHOLD && abs(velocityX) > Companion.SWIPE_VELOCITY_THRESHOLD && abs(
|
||||
diffY
|
||||
) <= Companion.SWIPE_THRESHOLD * 0.75f
|
||||
) {
|
||||
if (diffX > 0) {
|
||||
currentGestureDelegate?.onSwipeRight(velocityX, e2.x)
|
||||
} else {
|
||||
currentGestureDelegate?.onSwipeLeft(velocityX, e2.x)
|
||||
}
|
||||
result = true
|
||||
}
|
||||
} else if (abs(diffY) > Companion.SWIPE_THRESHOLD && abs(
|
||||
velocityY
|
||||
) > Companion.SWIPE_VELOCITY_THRESHOLD
|
||||
val diffY = e2.y - e1.y
|
||||
val diffX = e2.x - e1.x
|
||||
if (abs(diffX) <= abs(diffY)) {
|
||||
val sheetRect = Rect()
|
||||
bottom_nav.getGlobalVisibleRect(sheetRect)
|
||||
if (sheetRect.contains(
|
||||
e1.x.toInt(), e1.y.toInt()
|
||||
) && abs(diffY) > Companion.SWIPE_THRESHOLD && abs(velocityY) > Companion.SWIPE_VELOCITY_THRESHOLD && diffY <= 0
|
||||
) {
|
||||
if (diffY > 0) {
|
||||
currentGestureDelegate?.onSwipeBottom(e1.x, e1.y)
|
||||
// onSwipeBottom()
|
||||
} else {
|
||||
currentGestureDelegate?.onSwipeTop(e1.x, e1.y)
|
||||
}
|
||||
result = true
|
||||
val bottomSheetController =
|
||||
router.backstack.lastOrNull()?.controller() as? BottomSheetController
|
||||
bottomSheetController?.showSheet()
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
exception.printStackTrace()
|
||||
result = true
|
||||
}
|
||||
return result
|
||||
}
|
||||
@ -649,19 +604,13 @@ interface BottomNavBarInterface {
|
||||
|
||||
interface RootSearchInterface {
|
||||
fun expandSearch() {
|
||||
if (this is Controller) activity?.toolbar?.menu?.findItem(R.id.action_search)?.expandActionView()
|
||||
if (this is Controller) activity?.toolbar?.menu?.findItem(R.id.action_search)
|
||||
?.expandActionView()
|
||||
}
|
||||
}
|
||||
|
||||
interface SpinnerTitleInterface
|
||||
|
||||
interface OnTouchEventInterface {
|
||||
fun onTouchEvent(event: MotionEvent?)
|
||||
}
|
||||
|
||||
interface SwipeGestureInterface {
|
||||
fun onSwipeRight(x: Float, xPos: Float)
|
||||
fun onSwipeLeft(x: Float, xPos: Float)
|
||||
fun onSwipeTop(x: Float, y: Float)
|
||||
fun onSwipeBottom(x: Float, y: Float)
|
||||
interface BottomSheetController {
|
||||
fun showSheet()
|
||||
fun toggleSheet()
|
||||
fun handleSheetBack(): Boolean
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ class SearchActivity : MainActivity() {
|
||||
toolbar.navigationIcon = drawerArrow
|
||||
drawerArrow?.progress = 1f
|
||||
|
||||
if (to !is SpinnerTitleInterface) toolbar.removeSpinner()
|
||||
bottom_nav.gone()
|
||||
}
|
||||
|
||||
|
@ -524,29 +524,10 @@ class MangaDetailsController : BaseController,
|
||||
// Inflate our menu resource into the PopupMenu's Menu
|
||||
popup.menuInflater.inflate(R.menu.chapters_mat_single, popup.menu)
|
||||
|
||||
// Hide bookmark if bookmark
|
||||
popup.menu.findItem(R.id.action_bookmark).isVisible = false // !item.bookmark
|
||||
popup.menu.findItem(R.id.action_remove_bookmark).isVisible = false // item.bookmark
|
||||
|
||||
// Hide mark as unread when the chapter is unread
|
||||
// if (!item.read && item.last_page_read == 0) {
|
||||
popup.menu.findItem(R.id.action_mark_as_unread).isVisible = false
|
||||
// }
|
||||
|
||||
// Hide mark as read when the chapter is read
|
||||
// if (item.read) {
|
||||
popup.menu.findItem(R.id.action_mark_as_read).isVisible = false
|
||||
// }
|
||||
|
||||
// Set a listener so we are notified if a menu item is clicked
|
||||
popup.setOnMenuItemClickListener { menuItem ->
|
||||
val chapters = listOf(item)
|
||||
when (menuItem.itemId) {
|
||||
R.id.action_bookmark -> bookmarkChapters(chapters, true)
|
||||
R.id.action_remove_bookmark -> bookmarkChapters(chapters, false)
|
||||
R.id.action_mark_as_read -> markAsRead(chapters)
|
||||
R.id.action_mark_previous_as_read -> markPreviousAsRead(item)
|
||||
R.id.action_mark_as_unread -> markAsUnread(chapters)
|
||||
}
|
||||
true
|
||||
}
|
||||
@ -614,6 +595,7 @@ class MangaDetailsController : BaseController,
|
||||
presenter.getNextUnreadChapter() != null && !presenter.isLockedFromSearch
|
||||
menu.findItem(R.id.action_mark_all_as_unread).isVisible =
|
||||
!presenter.allUnread() && !presenter.isLockedFromSearch
|
||||
menu.findItem(R.id.action_mark_all_as_unread).isVisible = presenter.isTracked()
|
||||
val iconPrimary = view?.context?.getResourceColor(android.R.attr.textColorPrimary)
|
||||
?: Color.BLACK
|
||||
menu.findItem(R.id.action_download).icon?.mutate()?.setTint(iconPrimary)
|
||||
@ -647,29 +629,24 @@ class MangaDetailsController : BaseController,
|
||||
when (item.itemId) {
|
||||
R.id.action_edit -> {
|
||||
if (manga?.source == LocalSource.ID) {
|
||||
editMangaDialog =
|
||||
EditMangaDialog(
|
||||
this,
|
||||
presenter.manga
|
||||
)
|
||||
editMangaDialog = EditMangaDialog(
|
||||
this, presenter.manga
|
||||
)
|
||||
editMangaDialog?.showDialog(router)
|
||||
} else {
|
||||
if (manga?.hasCustomCover() == true) {
|
||||
MaterialDialog(activity!!).listItems(items = listOf(
|
||||
view!!.context.getString(
|
||||
R.string.action_edit_cover
|
||||
), view!!.context.getString(
|
||||
R.string.action_reset_cover
|
||||
)
|
||||
),
|
||||
waitForPositiveButton = false,
|
||||
selection = { _, index, _ ->
|
||||
when (index) {
|
||||
0 -> changeCover()
|
||||
else -> presenter.clearCover()
|
||||
}
|
||||
})
|
||||
.show()
|
||||
view!!.context.getString(
|
||||
R.string.action_edit_cover
|
||||
), view!!.context.getString(
|
||||
R.string.action_reset_cover
|
||||
)
|
||||
), waitForPositiveButton = false, selection = { _, index, _ ->
|
||||
when (index) {
|
||||
0 -> changeCover()
|
||||
else -> presenter.clearCover()
|
||||
}
|
||||
}).show()
|
||||
} else {
|
||||
changeCover()
|
||||
}
|
||||
@ -678,19 +655,17 @@ class MangaDetailsController : BaseController,
|
||||
R.id.action_open_in_web_view -> openInWebView()
|
||||
R.id.action_share -> prepareToShareManga()
|
||||
R.id.action_add_to_home_screen -> addToHomeScreen()
|
||||
R.id.action_refresh_tracking -> presenter.refreshTrackers()
|
||||
R.id.action_mark_all_as_read -> {
|
||||
MaterialDialog(view!!.context)
|
||||
.message(R.string.mark_all_as_read_message)
|
||||
MaterialDialog(view!!.context).message(R.string.mark_all_as_read_message)
|
||||
.positiveButton(R.string.action_mark_as_read) {
|
||||
markAsRead(presenter.chapters)
|
||||
}
|
||||
.negativeButton(android.R.string.cancel)
|
||||
.show()
|
||||
}.negativeButton(android.R.string.cancel).show()
|
||||
}
|
||||
R.id.action_mark_all_as_unread -> markAsUnread(presenter.chapters)
|
||||
R.id.download_next, R.id.download_next_5, R.id.download_next_10,
|
||||
R.id.download_custom, R.id.download_unread, R.id.download_all
|
||||
-> downloadChapters(item.itemId)
|
||||
R.id.download_next, R.id.download_next_5, R.id.download_custom, R.id.download_unread, R.id.download_all -> downloadChapters(
|
||||
item.itemId
|
||||
)
|
||||
else -> return super.onOptionsItemSelected(item)
|
||||
}
|
||||
return true
|
||||
@ -759,7 +734,6 @@ class MangaDetailsController : BaseController,
|
||||
val chaptersToDownload = when (choice) {
|
||||
R.id.download_next -> presenter.getUnreadChaptersSorted().take(1)
|
||||
R.id.download_next_5 -> presenter.getUnreadChaptersSorted().take(5)
|
||||
R.id.download_next_10 -> presenter.getUnreadChaptersSorted().take(10)
|
||||
R.id.download_custom -> {
|
||||
createActionModeIfNeeded()
|
||||
return
|
||||
|
@ -27,7 +27,6 @@ import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||
import eu.kanade.tachiyomi.util.view.snack
|
||||
import kotlinx.android.synthetic.main.download_bottom_sheet.*
|
||||
import kotlinx.android.synthetic.main.main_activity.*
|
||||
import kotlinx.android.synthetic.main.recent_chapters_controller.*
|
||||
import kotlinx.android.synthetic.main.recent_chapters_controller.empty_view
|
||||
import timber.log.Timber
|
||||
@ -87,10 +86,7 @@ class RecentChaptersController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
swipe_refresh.setOnRefreshListener {
|
||||
if (!LibraryUpdateService.isRunning()) {
|
||||
LibraryUpdateService.start(view.context)
|
||||
view.snack(R.string.updating_library) {
|
||||
anchorView = (this@RecentChaptersController.activity as? MainActivity)
|
||||
?.bottom_nav
|
||||
}
|
||||
snack = view.snack(R.string.updating_library)
|
||||
}
|
||||
// It can be a very long operation, so we disable swipe refresh and show a snackbar.
|
||||
swipe_refresh.isRefreshing = false
|
||||
|
@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.data.download.model.Download
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
|
||||
import eu.kanade.tachiyomi.ui.main.BottomSheetController
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.main.RootSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
@ -53,7 +54,8 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
RecentMangaAdapter.RecentsInterface,
|
||||
FlexibleAdapter.OnItemClickListener,
|
||||
FlexibleAdapter.OnItemMoveListener,
|
||||
RootSearchInterface {
|
||||
RootSearchInterface,
|
||||
BottomSheetController {
|
||||
|
||||
init {
|
||||
setHasOptionsMenu(true)
|
||||
@ -182,7 +184,7 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
swipe_refresh.isEnabled = actionState != ItemTouchHelper.ACTION_STATE_SWIPE
|
||||
}
|
||||
|
||||
override fun handleRootBack(): Boolean {
|
||||
override fun handleSheetBack(): Boolean {
|
||||
if (dl_bottom_sheet.sheetBehavior?.state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
dl_bottom_sheet.dismiss()
|
||||
return true
|
||||
@ -353,11 +355,11 @@ class RecentsController(bundle: Bundle? = null) : BaseController(bundle),
|
||||
}
|
||||
}
|
||||
|
||||
fun showDownloads() {
|
||||
override fun showSheet() {
|
||||
dl_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
}
|
||||
|
||||
fun toggleDownloads() {
|
||||
override fun toggleSheet() {
|
||||
if (dl_bottom_sheet.sheetBehavior?.isHideable == false) {
|
||||
if (showingDownloads) dl_bottom_sheet.dismiss()
|
||||
else dl_bottom_sheet.sheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
|
@ -340,6 +340,7 @@ fun Controller.scrollViewWith(
|
||||
val array = recycler.context.obtainStyledAttributes(attrsArray)
|
||||
val appBarHeight = array.getDimensionPixelSize(0, 0)
|
||||
array.recycle()
|
||||
swipeRefreshLayout?.setDistanceToTriggerSync(150.dpToPx)
|
||||
recycler.doOnApplyWindowInsets { view, insets, _ ->
|
||||
val headerHeight = insets.systemWindowInsetTop + appBarHeight
|
||||
if (!customPadding) view.updatePaddingRelative(
|
||||
|
@ -158,7 +158,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:text="@string/auto_hide_category_seeker" />
|
||||
android:text="@string/always_show_library_fast_scroll"/>
|
||||
|
||||
<com.google.android.material.checkbox.MaterialCheckBox
|
||||
android:id="@+id/hide_filters"
|
||||
|
@ -57,17 +57,6 @@
|
||||
android:textColor="?actionBarTintColor"
|
||||
android:textSize="20sp"
|
||||
tools:text="Title Text" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dropdown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="4dp"
|
||||
android:background="@drawable/round_ripple"
|
||||
android:src="@drawable/ic_arrow_drop_down_white_24dp"
|
||||
android:tint="?actionBarTintColor" />
|
||||
</LinearLayout>
|
||||
</eu.kanade.tachiyomi.ui.base.CenteredToolbar>
|
||||
|
||||
|
@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_filter"
|
||||
android:icon="@drawable/ic_filter_list_white_24dp"
|
||||
android:title="@string/action_filter"
|
||||
app:showAsAction="ifRoom">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/action_filter_read"
|
||||
android:checkable="true"
|
||||
android:title="@string/action_filter_read"/>
|
||||
<item
|
||||
android:id="@+id/action_filter_unread"
|
||||
android:checkable="true"
|
||||
android:title="@string/action_filter_unread"/>
|
||||
<item
|
||||
android:id="@+id/action_filter_downloaded"
|
||||
android:checkable="true"
|
||||
android:title="@string/action_filter_downloaded"/>
|
||||
<item
|
||||
android:id="@+id/action_filter_bookmarked"
|
||||
android:checkable="true"
|
||||
android:title="@string/action_filter_bookmarked"/>
|
||||
<item
|
||||
android:id="@+id/action_filter_empty"
|
||||
android:title="@string/action_filter_empty"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_sort"
|
||||
android:icon="@drawable/ic_sort_by_numeric_white_24dp"
|
||||
android:title="@string/action_sort"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:title="@string/action_display_mode"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/display_title"
|
||||
android:title="@string/show_title" />
|
||||
<item
|
||||
android:id="@+id/display_chapter_number"
|
||||
android:title="@string/show_chapter_number" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:title="@string/sorting_mode"
|
||||
app:showAsAction="never">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/sort_by_source"
|
||||
android:title="@string/sort_by_source" />
|
||||
<item
|
||||
android:id="@+id/sort_by_number"
|
||||
android:title="@string/sort_by_number" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:title="@string/manga_download"
|
||||
app:showAsAction="never" >
|
||||
<menu >
|
||||
<item
|
||||
android:id="@+id/download_next"
|
||||
android:title="@string/download_1" />
|
||||
<item
|
||||
android:id="@+id/download_next_5"
|
||||
android:title="@string/download_5" />
|
||||
<item
|
||||
android:id="@+id/download_next_10"
|
||||
android:title="@string/download_10" />
|
||||
<item
|
||||
android:id="@+id/download_custom"
|
||||
android:title="@string/download_custom" />
|
||||
<item
|
||||
android:id="@+id/download_unread"
|
||||
android:title="@string/download_unread" />
|
||||
<item
|
||||
android:id="@+id/download_all"
|
||||
android:title="@string/download_all" />
|
||||
</menu>
|
||||
</item>
|
||||
</menu>
|
@ -1,21 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/action_mark_as_read"
|
||||
android:title="@string/action_mark_as_read" />
|
||||
|
||||
<item android:id="@+id/action_mark_as_unread"
|
||||
android:title="@string/action_mark_as_unread" />
|
||||
|
||||
<item android:id="@+id/action_bookmark"
|
||||
android:title="@string/action_bookmark"
|
||||
android:visible="true" />
|
||||
|
||||
<item android:id="@+id/action_remove_bookmark"
|
||||
android:title="@string/action_remove_bookmark"
|
||||
android:visible="true" />
|
||||
|
||||
<item android:id="@+id/action_mark_previous_as_read"
|
||||
android:title="@string/action_mark_previous_as_read"/>
|
||||
</menu>
|
@ -37,14 +37,19 @@
|
||||
android:id="@+id/action_mark_all_as_read"
|
||||
android:icon="@drawable/ic_done_all_white_24dp"
|
||||
android:title="@string/action_mark_all_as_read"
|
||||
app:showAsAction="never" />
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_mark_all_as_unread"
|
||||
android:icon="@drawable/ic_done_all_white_24dp"
|
||||
android:title="@string/action_mark_all_as_unread"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_refresh_tracking"
|
||||
android:icon="@drawable/ic_refresh_white_24dp"
|
||||
android:title="@string/action_refresh_tracking"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:icon="@drawable/ic_edit_white_24dp"
|
||||
|
@ -81,6 +81,7 @@
|
||||
<string name="action_mark_as_read">Mark as read</string>
|
||||
<string name="action_mark_all_as_read">Mark all as read</string>
|
||||
<string name="action_mark_all_as_unread">Mark all as unread</string>
|
||||
<string name="action_refresh_tracking">Refresh tracking</string>
|
||||
<string name="action_mark_as_unread">Mark as unread</string>
|
||||
<string name="action_mark_previous_as_read">Mark previous as read</string>
|
||||
<string name="action_mark_multiple">Mark multiple</string>
|
||||
@ -122,7 +123,7 @@
|
||||
<string name="action_display_grid">Compact Grid</string>
|
||||
<string name="action_display_list">List</string>
|
||||
<string name="action_display_download_badge">Download badges</string>
|
||||
<string name="auto_hide_category_seeker">Auto-hide category seeker</string>
|
||||
<string name="always_show_library_fast_scroll">Always show library fast scroll</string>
|
||||
<string name="action_display_unread_badge">Unread badges</string>
|
||||
<string name="action_set_filter">Set filter</string>
|
||||
<string name="action_cancel">Cancel</string>
|
||||
@ -209,6 +210,7 @@
|
||||
<item quantity="one">%d category</item>
|
||||
<item quantity="other">%d categories</item>
|
||||
</plurals>
|
||||
<string name="top">Top</string>
|
||||
|
||||
<string name="pref_category_library_update">Updates</string>
|
||||
<string name="pref_library_update_interval">Library update frequency</string>
|
||||
|
Loading…
Reference in New Issue
Block a user