diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 8ae8a56916..9eb1919b21 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt index d0826f759f..73f47279ef 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/CenteredToolbar.kt @@ -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) - } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt index 6518a33e99..569f08e8a8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt @@ -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 } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt index a14d6ee580..168d5befbf 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt @@ -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(), FlexibleAdapter.OnItemClickListener, CatalogueAdapter.OnBrowseClickListener, RootSearchInterface, - + BottomSheetController, CatalogueAdapter.OnLatestClickListener { /** @@ -180,11 +181,11 @@ class CatalogueController : NucleusController(), } } - 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(), } } - 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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadBottomSheet.kt index be32b0b46a..13ec30531a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadBottomSheet.kt @@ -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 } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/DisplayBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/DisplayBottomSheet.kt index efef5bfac9..1cf9728375 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/DisplayBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/DisplayBottomSheet.kt @@ -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() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt index 2fbd915dfb..5d8518c965 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryAdapter.kt @@ -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 } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index d5175cc230..53c34bbf72 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -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 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 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 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 } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt index 70cb8ee7af..e7044ce456 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryHeaderItem.kt @@ -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 +) : AbstractHeaderItem() { override fun getLayoutRes(): Int { @@ -35,7 +42,7 @@ class LibraryHeaderItem(private val categoryF: (Int) -> Category, val catId: Int view: View, adapter: FlexibleAdapter> ): 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 { + 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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt index fe9b438fdf..36c00c8710 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryItem.kt @@ -28,6 +28,7 @@ class LibraryItem( val manga: LibraryManga, private val libraryLayout: Preference, private val fixedSize: Preference, + private val showFastScroll: Preference, header: LibraryHeaderItem? ) : AbstractSectionableItem(header), IFilterable { @@ -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()) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt index 3633557f19..a09885e373 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListHolder.kt @@ -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 { + marginEnd = (if (padEnd) 22 else 12).dpToPx + } + } + /** * Method called from [LibraryCategoryAdapter.onBindViewHolder]. It updates the data for this * holder with the given manga. diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index a9f2354b91..ed17f7b4e6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -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 ) ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index f8d0c5fcf3..bec3b0c768 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -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 } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt index 101e7153be..b25034f5ac 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/SearchActivity.kt @@ -51,7 +51,6 @@ class SearchActivity : MainActivity() { toolbar.navigationIcon = drawerArrow drawerArrow?.progress = 1f - if (to !is SpinnerTitleInterface) toolbar.removeSpinner() bottom_nav.gone() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt index 80d9a47576..07c5b2bd96 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsController.kt @@ -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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt index c0d402d57d..898360e947 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent_updates/RecentChaptersController.kt @@ -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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt index 0db6accabb..a170eb9a99 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recents/RecentsController.kt @@ -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 diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt index d0e65ad6a4..a1176a99d5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt @@ -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( diff --git a/app/src/main/res/layout/display_bottom_sheet.xml b/app/src/main/res/layout/display_bottom_sheet.xml index 2797cd3922..a112dd34bc 100644 --- a/app/src/main/res/layout/display_bottom_sheet.xml +++ b/app/src/main/res/layout/display_bottom_sheet.xml @@ -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"/> - - diff --git a/app/src/main/res/menu/chapters.xml b/app/src/main/res/menu/chapters.xml deleted file mode 100644 index c0e1b2b5ab..0000000000 --- a/app/src/main/res/menu/chapters.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/chapters_mat_single.xml b/app/src/main/res/menu/chapters_mat_single.xml index 40c3865eb7..7fa63341f9 100644 --- a/app/src/main/res/menu/chapters_mat_single.xml +++ b/app/src/main/res/menu/chapters_mat_single.xml @@ -1,21 +1,6 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/manga_details.xml b/app/src/main/res/menu/manga_details.xml index 350fff59e9..0c7e02414d 100644 --- a/app/src/main/res/menu/manga_details.xml +++ b/app/src/main/res/menu/manga_details.xml @@ -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" /> + + Mark as read Mark all as read Mark all as unread + Refresh tracking Mark as unread Mark previous as read Mark multiple @@ -122,7 +123,7 @@ Compact Grid List Download badges - Auto-hide category seeker + Always show library fast scroll Unread badges Set filter Cancel @@ -209,6 +210,7 @@ %d category %d categories + Top Updates Library update frequency