From c13b6cbe914f022de9b10baf924f719334871ded Mon Sep 17 00:00:00 2001 From: Jay Date: Fri, 3 Apr 2020 02:33:05 -0400 Subject: [PATCH] Added swipe to refresh to library Plus increased horizonatal swipe distance --- .../data/library/LibraryUpdateService.kt | 5 +- .../data/preference/PreferenceKeys.kt | 2 + .../data/preference/PreferencesHelper.kt | 2 + .../ui/library/LibraryListController.kt | 66 ++++++++++++++++--- .../ui/library/filter/FilterBottomSheet.kt | 4 +- .../ui/manga/MangaDetailsController.kt | 3 +- .../ui/setting/SettingsLibraryController.kt | 10 +++ .../res/layout/library_list_controller.xml | 6 +- app/src/main/res/values/strings.xml | 6 ++ 9 files changed, 89 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index 63604062d4..fe52b7c376 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource import eu.kanade.tachiyomi.util.lang.chop +import eu.kanade.tachiyomi.util.system.executeOnIO import eu.kanade.tachiyomi.util.system.notification import eu.kanade.tachiyomi.util.system.notificationManager import kotlinx.coroutines.CoroutineExceptionHandler @@ -360,7 +361,9 @@ class LibraryUpdateService( mangaToUpdate.addAll(mangaToAdd) while (count < mangaToUpdate.size) { val shouldDownload = (downloadNew && (categoriesToDownload.isEmpty() || - mangaToUpdate[count].category in categoriesToDownload)) + mangaToUpdate[count].category in categoriesToDownload || + db.getCategoriesForManga(mangaToUpdate[count]).executeOnIO() + .any { (it.id ?: -1) in categoriesToDownload })) if (updateMangaChapters(mangaToUpdate[count], count, shouldDownload)) { hasDownloads = true } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index 1fafd9d93d..9f89e99c86 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt @@ -143,6 +143,8 @@ object PreferenceKeys { const val refreshCoversToo = "refresh_covers_too" + const val updateOnRefresh = "update_on_refresh" + const val keepCatSort = "keep_cat_sort" const val alwaysShowChapterTransition = "always_show_chapter_transition" 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 5322f953e8..3004c2ee20 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 @@ -239,6 +239,8 @@ class PreferencesHelper(val context: Context) { fun refreshCoversToo() = rxPrefs.getBoolean(Keys.refreshCoversToo, true) + fun updateOnRefresh() = rxPrefs.getInteger(Keys.updateOnRefresh, -1) + fun extensionUpdatesCount() = rxPrefs.getInteger("ext_updates_count", 0) fun showRecentUpdates() = rxPrefs.getBoolean("show_recents", false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt index ffde9c0fdf..86b6f68a01 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryListController.kt @@ -12,7 +12,6 @@ import android.view.MotionEvent import android.view.View import android.view.ViewGroup import androidx.appcompat.view.ActionMode -import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -20,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.checkbox.checkBoxPrompt import com.afollestad.materialdialogs.checkbox.isCheckPromptChecked +import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeType import com.google.android.material.bottomsheet.BottomSheetBehavior @@ -81,7 +81,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), private var nextCategory: Int? = null private var ogCategory: Int? = null private var prevCategory: Int? = null - private val swipeDistance = 300f + private val swipeDistance = 500f private var flinging = false private var isDragging = false private val scrollDistanceTilHidden = 1000.dpToPx @@ -189,6 +189,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), if (lockedY) return if (distance > 60 && abs(event.rawY - startPosY!!) <= 30 && !lockedRecycler) { + swipe_refresh.isEnabled = false lockedRecycler = true switchingCategories = true recycler.suppressLayout(true) @@ -203,7 +204,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), recycler_layout.x = sign * distance.pow(0.6f) recycler_layout.alpha = 1f } else if (distance <= swipeDistance * 1.1f) { - recycler_layout.x = sign * (distance / 100f).pow(3.5f) + recycler_layout.x = sign * (distance / (swipeDistance / 3f)).pow(3.5f) recycler_layout.alpha = (1f - (distance - (swipeDistance * 0.1f)) / swipeDistance) if (moved) { @@ -215,8 +216,8 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), scrollToHeader((if (sign <= 0) nextCategory else prevCategory) ?: -1) moved = true } - recycler_layout.x = -sign * (max(0f, (swipeDistance * 2 - distance)) / 100f) - .pow(3.5f) + 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) } @@ -245,6 +246,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), } private fun resetScrollingValues() { + swipe_refresh.isEnabled = true startPosX = null startPosY = null nextCategory = null @@ -254,6 +256,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), } private fun resetRecyclerY(animated: Boolean = false, time: Long = 100) { + swipe_refresh.isEnabled = true moved = false lockedRecycler = false if (animated) { @@ -308,11 +311,53 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), val tv = TypedValue() activity!!.theme.resolveAttribute(R.attr.actionBarTintColor, tv, true) - scrollViewWith(recycler) { insets -> - fast_scroller.updateLayoutParams { + scrollViewWith(recycler, swipeRefreshLayout = swipe_refresh) { insets -> + fast_scroller.updateLayoutParams { topMargin = insets.systemWindowInsetTop } } + + swipe_refresh.setOnRefreshListener { + swipe_refresh.isRefreshing = false + if (!LibraryUpdateService.isRunning()) { + when { + presenter.allCategories.size <= 1 -> updateLibrary() + preferences.updateOnRefresh().getOrDefault() == -1 -> { + MaterialDialog(activity!!).title(R.string.what_should_update) + .negativeButton(android.R.string.cancel) + .listItemsSingleChoice(items = listOf( + view.context.getString( + R.string.top_category, presenter.allCategories.first().name + ), view.context.getString( + R.string.categories_in_global_update + ) + ), selection = { _, index, _ -> + preferences.updateOnRefresh().set(index) + when (index) { + 0 -> updateLibrary(presenter.allCategories.first()) + else -> updateLibrary() + } + }) + .positiveButton(R.string.action_update) + .show() + } + else -> { + when (preferences.updateOnRefresh().getOrDefault()) { + 0 -> updateLibrary(presenter.allCategories.first()) + else -> updateLibrary() + } + } + } + } + } + } + + private fun updateLibrary(category: Category? = null) { + val view = view ?: return + LibraryUpdateService.start(view.context, category) + snack = view.snack(R.string.updating_library) { + anchorView = bottom_sheet + } } private fun setRecyclerLayout() { @@ -738,7 +783,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), val sign = sign(x).roundToInt() if ((sign < 0 && nextCategory == null) || (sign > 0) && prevCategory == null) return val distance = recycler_layout.alpha - val speed = max(3000f / abs(x), 0.75f) + val speed = max(5000f / abs(x), 0.75f) if (sign(recycler_layout.x) == sign(x)) { flinging = true val duration = (distance * 100 * speed).toLong() @@ -747,7 +792,8 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), swipeDistance) translationXAnimator.duration = duration translationXAnimator.addUpdateListener { animation -> - recycler_layout.x = sign * (animation.animatedValue as Float / 100f).pow(3.5f) + recycler_layout.x = sign * + (animation.animatedValue as Float / (swipeDistance / 3f)).pow(3.5f) } val translationAlphaAnimator = ValueAnimator.ofFloat(recycler_layout.alpha, 0f) @@ -759,7 +805,7 @@ LibraryListController(bundle: Bundle? = null) : LibraryController(bundle), set.start() set.addListener(object : Animator.AnimatorListener { override fun onAnimationEnd(animation: Animator?) { - recycler_layout.x = -sign * (swipeDistance / 100f).pow(3.5f) + 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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt index 1b033fada8..af8c6abc89 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt @@ -75,8 +75,8 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri sheetBehavior = BottomSheetBehavior.from(this) sheetBehavior?.isHideable = true pager = pagerView - val shadow2: View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2) - val shadow: View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow) + val shadow2: View = (pagerView.parent.parent as ViewGroup).findViewById(R.id.shadow2) + val shadow: View = (pagerView.parent.parent as ViewGroup).findViewById(R.id.shadow) sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onSlide(bottomSheet: View, progress: Float) { pill.alpha = (1 - max(0f, progress)) * 0.25f 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 1534c37803..cbaf9e9599 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 @@ -607,7 +607,8 @@ class MangaDetailsController : BaseController, editItem.isVisible = presenter.manga.favorite && !presenter.isLockedFromSearch editItem.title = view?.context?.getString(if (manga?.source == LocalSource.ID) R.string.action_edit else R.string.action_edit_cover) - menu.findItem(R.id.action_download).isVisible = !presenter.isLockedFromSearch + menu.findItem(R.id.action_download).isVisible = !presenter.isLockedFromSearch && + manga?.source != LocalSource.ID menu.findItem(R.id.action_add_to_home_screen).isVisible = !presenter.isLockedFromSearch menu.findItem(R.id.action_mark_all_as_read).isVisible = presenter.getNextUnreadChapter() != null && !presenter.isLockedFromSearch diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt index 5b84fd5240..7adb0bf956 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt @@ -92,6 +92,16 @@ class SettingsLibraryController : SettingsController() { preferenceCategory { titleRes = R.string.pref_category_library_update + intListPreference(activity) { + key = Keys.updateOnRefresh + titleRes = R.string.categories_on_manual + + entriesRes = arrayOf( + R.string.first_category, R.string.categories_in_global_update + ) + entryRange = 0..1 + defaultValue = -1 + } intListPreference(activity) { key = Keys.libraryUpdateInterval titleRes = R.string.pref_library_update_interval diff --git a/app/src/main/res/layout/library_list_controller.xml b/app/src/main/res/layout/library_list_controller.xml index cb7016ad26..4a87ff2f82 100644 --- a/app/src/main/res/layout/library_list_controller.xml +++ b/app/src/main/res/layout/library_list_controller.xml @@ -5,6 +5,10 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/library_layout" android:layout_height="match_parent"> + + - Remove download Start downloading now Update library + Update Edit Edit cover Reset cover @@ -456,6 +457,11 @@ Local Remove from library? Switch to Drag & Drop mode? + What should update? + Top category (%1$s) + First category + Categories to update when manually refreshing + All categories in global update Keep sorting by %1$s Delete category? Manga in this category will moved into the