|
|
@ -1,14 +1,20 @@
|
|
|
|
package eu.kanade.tachiyomi.ui.library
|
|
|
|
package eu.kanade.tachiyomi.ui.library
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import android.animation.Animator
|
|
|
|
|
|
|
|
import android.animation.AnimatorSet
|
|
|
|
|
|
|
|
import android.animation.ValueAnimator
|
|
|
|
import android.graphics.Rect
|
|
|
|
import android.graphics.Rect
|
|
|
|
|
|
|
|
import android.os.Build
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.util.TypedValue
|
|
|
|
import android.util.TypedValue
|
|
|
|
import android.view.Gravity
|
|
|
|
import android.view.Gravity
|
|
|
|
import android.view.LayoutInflater
|
|
|
|
import android.view.LayoutInflater
|
|
|
|
|
|
|
|
import android.view.MotionEvent
|
|
|
|
import android.view.View
|
|
|
|
import android.view.View
|
|
|
|
import android.view.ViewGroup
|
|
|
|
import android.view.ViewGroup
|
|
|
|
import androidx.appcompat.view.ActionMode
|
|
|
|
import androidx.appcompat.view.ActionMode
|
|
|
|
import androidx.appcompat.widget.PopupMenu
|
|
|
|
import androidx.appcompat.widget.PopupMenu
|
|
|
|
|
|
|
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
|
|
import androidx.core.math.MathUtils.clamp
|
|
|
|
import androidx.core.math.MathUtils.clamp
|
|
|
|
import androidx.recyclerview.widget.GridLayoutManager
|
|
|
|
import androidx.recyclerview.widget.GridLayoutManager
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
@ -26,6 +32,7 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
|
|
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
|
|
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
|
|
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
|
|
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
|
|
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
|
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
|
|
|
|
|
|
|
import eu.kanade.tachiyomi.ui.main.OnTouchEventInterface
|
|
|
|
import eu.kanade.tachiyomi.ui.main.SpinnerTitleInterface
|
|
|
|
import eu.kanade.tachiyomi.ui.main.SpinnerTitleInterface
|
|
|
|
import eu.kanade.tachiyomi.ui.main.SwipeGestureInterface
|
|
|
|
import eu.kanade.tachiyomi.ui.main.SwipeGestureInterface
|
|
|
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
|
|
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
|
|
@ -33,6 +40,7 @@ import eu.kanade.tachiyomi.util.system.launchUI
|
|
|
|
import eu.kanade.tachiyomi.util.view.inflate
|
|
|
|
import eu.kanade.tachiyomi.util.view.inflate
|
|
|
|
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
|
|
|
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
|
|
|
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.updatePaddingRelative
|
|
|
|
import eu.kanade.tachiyomi.util.view.updatePaddingRelative
|
|
|
|
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.*
|
|
|
@ -40,8 +48,13 @@ import kotlinx.android.synthetic.main.library_list_controller.*
|
|
|
|
import kotlinx.android.synthetic.main.main_activity.*
|
|
|
|
import kotlinx.android.synthetic.main.main_activity.*
|
|
|
|
import kotlinx.android.synthetic.main.spinner_title.view.*
|
|
|
|
import kotlinx.android.synthetic.main.spinner_title.view.*
|
|
|
|
import kotlinx.coroutines.delay
|
|
|
|
import kotlinx.coroutines.delay
|
|
|
|
|
|
|
|
import timber.log.Timber
|
|
|
|
import java.util.Locale
|
|
|
|
import java.util.Locale
|
|
|
|
|
|
|
|
import kotlin.math.abs
|
|
|
|
import kotlin.math.max
|
|
|
|
import kotlin.math.max
|
|
|
|
|
|
|
|
import kotlin.math.min
|
|
|
|
|
|
|
|
import kotlin.math.roundToInt
|
|
|
|
|
|
|
|
import kotlin.math.sign
|
|
|
|
|
|
|
|
|
|
|
|
class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
FlexibleAdapter.OnItemClickListener,
|
|
|
|
FlexibleAdapter.OnItemClickListener,
|
|
|
@ -49,6 +62,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
FlexibleAdapter.OnItemMoveListener,
|
|
|
|
FlexibleAdapter.OnItemMoveListener,
|
|
|
|
LibraryCategoryAdapter.LibraryListener,
|
|
|
|
LibraryCategoryAdapter.LibraryListener,
|
|
|
|
SpinnerTitleInterface,
|
|
|
|
SpinnerTitleInterface,
|
|
|
|
|
|
|
|
OnTouchEventInterface,
|
|
|
|
SwipeGestureInterface {
|
|
|
|
SwipeGestureInterface {
|
|
|
|
|
|
|
|
|
|
|
|
private lateinit var adapter: LibraryCategoryAdapter
|
|
|
|
private lateinit var adapter: LibraryCategoryAdapter
|
|
|
@ -66,6 +80,17 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
|
|
|
|
|
|
|
|
private var switchingCategories = false
|
|
|
|
private var switchingCategories = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var startPosX:Float? = null
|
|
|
|
|
|
|
|
var startPosY:Float? = null
|
|
|
|
|
|
|
|
var moved = false
|
|
|
|
|
|
|
|
var lockedRecycler = false
|
|
|
|
|
|
|
|
var lockedY = false
|
|
|
|
|
|
|
|
var nextCategory:Int? = null
|
|
|
|
|
|
|
|
var ogCategory:Int? = null
|
|
|
|
|
|
|
|
var prevCategory:Int? = null
|
|
|
|
|
|
|
|
private val swipeDistance = 300f
|
|
|
|
|
|
|
|
var flinging = false
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Recycler view of the list of manga.
|
|
|
|
* Recycler view of the list of manga.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -73,7 +98,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
|
|
|
|
|
|
|
|
override fun contentView():View = recycler_layout
|
|
|
|
override fun contentView():View = recycler_layout
|
|
|
|
|
|
|
|
|
|
|
|
/* override fun getTitle(): String? {
|
|
|
|
override fun getTitle(): String? {
|
|
|
|
return if (::customTitleSpinner.isInitialized) customTitleSpinner.category_title.text.toString()
|
|
|
|
return if (::customTitleSpinner.isInitialized) customTitleSpinner.category_title.text.toString()
|
|
|
|
else super.getTitle()
|
|
|
|
else super.getTitle()
|
|
|
|
// when {
|
|
|
|
// when {
|
|
|
@ -81,7 +106,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
// spinnerAdapter?.array?.size == 1 -> return spinnerAdapter?.array?.firstOrNull()
|
|
|
|
// spinnerAdapter?.array?.size == 1 -> return spinnerAdapter?.array?.firstOrNull()
|
|
|
|
// else -> return super.getTitle()
|
|
|
|
// else -> return super.getTitle()
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
@ -115,6 +140,156 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun onTouchEvent(event: MotionEvent?) {
|
|
|
|
|
|
|
|
if (event == null) {
|
|
|
|
|
|
|
|
resetScrollingValues()
|
|
|
|
|
|
|
|
resetRecyclerY()
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flinging) return
|
|
|
|
|
|
|
|
val sheetRect = Rect()
|
|
|
|
|
|
|
|
val recyclerRect = Rect()
|
|
|
|
|
|
|
|
bottom_sheet.getGlobalVisibleRect(sheetRect)
|
|
|
|
|
|
|
|
view?.getGlobalVisibleRect(recyclerRect)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (sheetRect.contains(event.x.toInt(), event.y.toInt()) ||
|
|
|
|
|
|
|
|
!recyclerRect.contains(event.x.toInt(), event.y.toInt())) {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (startPosX == null) {
|
|
|
|
|
|
|
|
startPosX = event.rawX
|
|
|
|
|
|
|
|
startPosY = event.rawY
|
|
|
|
|
|
|
|
val position =
|
|
|
|
|
|
|
|
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
|
|
|
|
|
|
|
val order = when (val item = adapter.getItem(position)) {
|
|
|
|
|
|
|
|
is LibraryHeaderItem -> item.category.order
|
|
|
|
|
|
|
|
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
|
|
|
|
|
|
|
|
else -> null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (order != null) {
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else 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) {
|
|
|
|
|
|
|
|
lockedRecycler = true
|
|
|
|
|
|
|
|
switchingCategories = true
|
|
|
|
|
|
|
|
if ((prevCategory == null && sign > 0) || (nextCategory == null && sign < 0)) {
|
|
|
|
|
|
|
|
recycler_layout.x = 0f
|
|
|
|
|
|
|
|
recycler_layout.alpha = 1f
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
recycler.suppressLayout(true)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (!lockedRecycler && abs(event.rawY - startPosY!!) > 30) {
|
|
|
|
|
|
|
|
lockedY = true
|
|
|
|
|
|
|
|
resetRecyclerY()
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((prevCategory == null && sign > 0) || (nextCategory == null && sign < 0)) {
|
|
|
|
|
|
|
|
resetRecyclerY()
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (abs(event.rawY - startPosY!!) <= 30 || recycler.isLayoutSuppressed
|
|
|
|
|
|
|
|
|| lockedRecycler) {
|
|
|
|
|
|
|
|
if (distance <= swipeDistance * 1.1f) {
|
|
|
|
|
|
|
|
recycler_layout.x = (max(0f, distance - 50f) * sign) / 3
|
|
|
|
|
|
|
|
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 = ((distance - swipeDistance * 2) * sign) / 3
|
|
|
|
|
|
|
|
recycler_layout.alpha = ((distance - swipeDistance * 1.1f) / swipeDistance)
|
|
|
|
|
|
|
|
if (sign > 0) {
|
|
|
|
|
|
|
|
recycler_layout.x = min(0f, recycler_layout.x)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
recycler_layout.x = max(0f, recycler_layout.x)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
recycler_layout.alpha = min(1f, recycler_layout.alpha)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (event.actionMasked == MotionEvent.ACTION_UP) {
|
|
|
|
|
|
|
|
recycler_layout.post {
|
|
|
|
|
|
|
|
if (!flinging) {
|
|
|
|
|
|
|
|
resetScrollingValues()
|
|
|
|
|
|
|
|
resetRecyclerY(true)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun resetScrollingValues() {
|
|
|
|
|
|
|
|
startPosX = null
|
|
|
|
|
|
|
|
startPosY = null
|
|
|
|
|
|
|
|
nextCategory = null
|
|
|
|
|
|
|
|
prevCategory = null
|
|
|
|
|
|
|
|
ogCategory = null
|
|
|
|
|
|
|
|
lockedY = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun resetRecyclerY(animated: Boolean = false, time: Long = 100) {
|
|
|
|
|
|
|
|
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 {
|
|
|
|
override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
|
|
|
|
return inflater.inflate(R.layout.library_list_controller, container, false)
|
|
|
|
return inflater.inflate(R.layout.library_list_controller, container, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -133,7 +308,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
recycler.setHasFixedSize(true)
|
|
|
|
recycler.setHasFixedSize(true)
|
|
|
|
recycler.adapter = adapter
|
|
|
|
recycler.adapter = adapter
|
|
|
|
adapter.fastScroller = fast_scroller
|
|
|
|
//adapter.fastScroller = fast_scroller
|
|
|
|
recycler.addOnScrollListener(scrollListener)
|
|
|
|
recycler.addOnScrollListener(scrollListener)
|
|
|
|
|
|
|
|
|
|
|
|
val tv = TypedValue()
|
|
|
|
val tv = TypedValue()
|
|
|
@ -258,14 +433,26 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun scrollToHeader(pos: Int, fade:Boolean = false) {
|
|
|
|
private fun scrollToHeader(pos: Int) {
|
|
|
|
val headerPosition = adapter.indexOf(pos)
|
|
|
|
val headerPosition = adapter.indexOf(pos)
|
|
|
|
switchingCategories = true
|
|
|
|
switchingCategories = true
|
|
|
|
if (headerPosition > -1) {
|
|
|
|
if (headerPosition > -1) {
|
|
|
|
activity?.appbar?.y = 0f
|
|
|
|
val appbar = activity?.appbar
|
|
|
|
|
|
|
|
//if (headerPosition == 0)
|
|
|
|
|
|
|
|
//activity?.appbar?.y = 0f
|
|
|
|
recycler.suppressLayout(true)
|
|
|
|
recycler.suppressLayout(true)
|
|
|
|
|
|
|
|
val appbarOffset =
|
|
|
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
|
|
|
|
|
if (appbar?.y ?: 0f > -20) 0 else
|
|
|
|
|
|
|
|
(appbar?.y?.plus(view?.rootWindowInsets?.systemWindowInsetTop ?: 0)
|
|
|
|
|
|
|
|
?: 0f).roundToInt() + 10.dpToPx
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
}
|
|
|
|
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
|
|
|
(recycler.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(
|
|
|
|
headerPosition, if (headerPosition == 0) 0 else (-30).dpToPx
|
|
|
|
headerPosition, (if (headerPosition == 0) 0 else (-28).dpToPx)
|
|
|
|
|
|
|
|
+ appbarOffset
|
|
|
|
)
|
|
|
|
)
|
|
|
|
recycler.suppressLayout(false)
|
|
|
|
recycler.suppressLayout(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -349,6 +536,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun startReading(position: Int) {
|
|
|
|
override fun startReading(position: Int) {
|
|
|
|
|
|
|
|
if (recyclerIsScrolling()) return
|
|
|
|
if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
|
|
|
if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
|
|
|
toggleSelection(position)
|
|
|
|
toggleSelection(position)
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -381,7 +569,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
* @return true if the item should be selected, false otherwise.
|
|
|
|
* @return true if the item should be selected, false otherwise.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
override fun onItemClick(view: View?, position: Int): Boolean {
|
|
|
|
override fun onItemClick(view: View?, position: Int): Boolean {
|
|
|
|
if (switchingCategories) return false
|
|
|
|
if (recyclerIsScrolling()) return false
|
|
|
|
val item = adapter.getItem(position) as? LibraryItem ?: return false
|
|
|
|
val item = adapter.getItem(position) as? LibraryItem ?: return false
|
|
|
|
return if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
|
|
|
return if (adapter.mode == SelectableAdapter.Mode.MULTI) {
|
|
|
|
lastClickPosition = position
|
|
|
|
lastClickPosition = position
|
|
|
@ -399,6 +587,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
* @param position the position of the element clicked.
|
|
|
|
* @param position the position of the element clicked.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
override fun onItemLongClick(position: Int) {
|
|
|
|
override fun onItemLongClick(position: Int) {
|
|
|
|
|
|
|
|
if (recyclerIsScrolling()) return
|
|
|
|
createActionModeIfNeeded()
|
|
|
|
createActionModeIfNeeded()
|
|
|
|
when {
|
|
|
|
when {
|
|
|
|
lastClickPosition == -1 -> setSelection(position)
|
|
|
|
lastClickPosition == -1 -> setSelection(position)
|
|
|
@ -586,6 +775,7 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
override fun onSwipeRight(x: Float, y: Float) = goToNextCategory(x, y,1)
|
|
|
|
override fun onSwipeRight(x: Float, y: Float) = goToNextCategory(x, y,1)
|
|
|
|
|
|
|
|
|
|
|
|
private fun goToNextCategory(x: Float, y: Float, offset: Int) {
|
|
|
|
private fun goToNextCategory(x: Float, y: Float, offset: Int) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
val sheetRect = Rect()
|
|
|
|
val sheetRect = Rect()
|
|
|
|
val recyclerRect = Rect()
|
|
|
|
val recyclerRect = Rect()
|
|
|
|
bottom_sheet.getGlobalVisibleRect(sheetRect)
|
|
|
|
bottom_sheet.getGlobalVisibleRect(sheetRect)
|
|
|
@ -594,13 +784,58 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
if (sheetRect.contains(x.toInt(), y.toInt()) ||
|
|
|
|
if (sheetRect.contains(x.toInt(), y.toInt()) ||
|
|
|
|
!recyclerRect.contains(x.toInt(), y.toInt())) {
|
|
|
|
!recyclerRect.contains(x.toInt(), y.toInt())) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
//jumpToCategory(offset)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (lockedRecycler && abs(x) > 1000f) {
|
|
|
|
|
|
|
|
val sign = sign(x).roundToInt()
|
|
|
|
|
|
|
|
val distance = recycler_layout.alpha
|
|
|
|
|
|
|
|
val speed = max(3000f / abs(x), 0.75f)
|
|
|
|
|
|
|
|
Timber.d("Flinged $distance, velo ${abs(x)}, speed $speed")
|
|
|
|
|
|
|
|
if (sign(recycler_layout.x) == sign(x)) {
|
|
|
|
|
|
|
|
flinging = true
|
|
|
|
|
|
|
|
val duration = (distance * 100 * speed).toLong()
|
|
|
|
|
|
|
|
val set = AnimatorSet()
|
|
|
|
|
|
|
|
val translationXAnimator = ValueAnimator.ofFloat(recycler_layout.x, sign * 100f)
|
|
|
|
|
|
|
|
translationXAnimator.duration = duration
|
|
|
|
|
|
|
|
translationXAnimator.addUpdateListener { animation ->
|
|
|
|
|
|
|
|
recycler_layout.x = animation.animatedValue as Float
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 * 100f
|
|
|
|
|
|
|
|
recycler_layout.alpha = 0f
|
|
|
|
|
|
|
|
scrollToHeader((if (sign <= 0) nextCategory else prevCategory) ?: -1)
|
|
|
|
|
|
|
|
resetScrollingValues()
|
|
|
|
|
|
|
|
resetRecyclerY(true, (100 * speed).toLong())
|
|
|
|
|
|
|
|
flinging = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun onAnimationCancel(animation: Animator?) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun onAnimationRepeat(animation: Animator?) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun onAnimationStart(animation: Animator?) {}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun jumpToCategory(offset: Int) {
|
|
|
|
val position =
|
|
|
|
val position =
|
|
|
|
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
|
|
|
(recycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
|
|
|
|
val order = when (val item = adapter.getItem(position)) {
|
|
|
|
val order = when (val item = adapter.getItem(position)) {
|
|
|
|
is LibraryHeaderItem -> item.category.order
|
|
|
|
is LibraryHeaderItem -> item.category.order
|
|
|
|
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
|
|
|
|
is LibraryItem -> presenter.categories.find { it.id == item.manga.category }?.order
|
|
|
|
?.plus(if (offset < 0) 1 else 0)
|
|
|
|
|
|
|
|
else -> null
|
|
|
|
else -> null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (order != null) {
|
|
|
|
if (order != null) {
|
|
|
@ -608,9 +843,11 @@ class LibraryListController(bundle: Bundle? = null) : LibraryController(bundle),
|
|
|
|
while (adapter.indexOf(newOffset) == -1 && presenter.categories.any { it.order == newOffset }) {
|
|
|
|
while (adapter.indexOf(newOffset) == -1 && presenter.categories.any { it.order == newOffset }) {
|
|
|
|
newOffset += offset
|
|
|
|
newOffset += offset
|
|
|
|
}
|
|
|
|
}
|
|
|
|
scrollToHeader (newOffset, true)
|
|
|
|
scrollToHeader(newOffset)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override fun popUpMenu(): PopupMenu = titlePopupMenu
|
|
|
|
override fun popUpMenu(): PopupMenu = titlePopupMenu
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun recyclerIsScrolling() = switchingCategories || lockedRecycler || lockedY
|
|
|
|
}
|
|
|
|
}
|