From 73373cab56add379cb7860014a792bb4800e0272 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 4 Apr 2020 16:11:00 -0400 Subject: [PATCH] Added option to globally sort all manga's chapters Fyi this is going to break your current sorting Also made it more obvious the entire chapter filter header is clickable --- .../tachiyomi/data/database/models/Manga.kt | 20 +++ .../data/preference/PreferencesHelper.kt | 2 +- .../ui/manga/MangaDetailsPresenter.kt | 33 ++-- .../tachiyomi/ui/manga/MangaHeaderHolder.kt | 4 +- .../manga/chapter/ChaptersSortBottomSheet.kt | 17 +- .../tachiyomi/util/view/ViewExtensions.kt | 20 ++- .../res/drawable/fast_scroll_background.xml | 2 +- .../res/layout/chapter_sort_bottom_sheet.xml | 31 +++- app/src/main/res/layout/manga_header_item.xml | 154 ++++++++++-------- app/src/main/res/values/strings.xml | 2 + 10 files changed, 177 insertions(+), 108 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt index e50d2ac22b..7e63546f36 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/models/Manga.kt @@ -27,8 +27,11 @@ interface Manga : SManga { fun setChapterOrder(order: Int) { setFlags(order, SORT_MASK) + setFlags(SORT_LOCAL, SORT_SELF_MASK) } + fun setSortToGlobal() = setFlags(SORT_GLOBAL, SORT_SELF_MASK) + private fun setFlags(flag: Int, mask: Int) { chapter_flags = chapter_flags and mask.inv() or (flag and mask) } @@ -37,6 +40,15 @@ interface Manga : SManga { return chapter_flags and SORT_MASK == SORT_DESC } + fun sortDescending(defaultDesc: Boolean): Boolean { + return if (chapter_flags and SORT_SELF_MASK == SORT_GLOBAL) defaultDesc + else sortDescending() + } + + fun showChapterTitle(defaultShow: Boolean): Boolean { + return chapter_flags and DISPLAY_MASK == DISPLAY_NUMBER + } + fun mangaType(): Int { val sourceName = Injekt.get().getOrStub(source).name val currentTags = genre?.split(",")?.map { it.trim().toLowerCase(Locale.US) } @@ -131,6 +143,14 @@ interface Manga : SManga { const val SORT_ASC = 0x00000001 const val SORT_MASK = 0x00000001 + const val SORT_GLOBAL = 0x00000000 + const val SORT_LOCAL = 0x00001000 + const val SORT_SELF_MASK = 0x00001000 + + /*const val HIDE_GLOBAL = 0x00000000 + const val HIDE_LOCAL = 0x00010000 + const val HIDE_SELF_MASK = 0x00010000*/ + // Generic filter that does not filter anything const val SHOW_ALL = 0x00000000 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 b4e2f69dfd..8ae8a56916 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 @@ -181,7 +181,7 @@ class PreferencesHelper(val context: Context) { fun uniformGrid() = rxPrefs.getBoolean(Keys.uniformGrid, true) - fun libraryAsSingleList() = rxPrefs.getBoolean(Keys.libraryAsSingleList, false) + fun chaptersDescAsDefault() = rxPrefs.getBoolean("chapters_desc_as_default", true) fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt index b0f40bd9ac..9a55980e19 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaDetailsPresenter.kt @@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.data.download.model.DownloadQueue import eu.kanade.tachiyomi.data.library.LibraryServiceListener import eu.kanade.tachiyomi.data.library.LibraryUpdateService import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.source.LocalSource @@ -189,37 +190,27 @@ class MangaDetailsPresenter( /** * Whether the display only downloaded filter is enabled. */ - fun onlyDownloaded(): Boolean { - return manga.downloadedFilter == Manga.SHOW_DOWNLOADED - } + fun onlyDownloaded() = manga.downloadedFilter == Manga.SHOW_DOWNLOADED /** * Whether the display only downloaded filter is enabled. */ - fun onlyBookmarked(): Boolean { - return manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED - } + fun onlyBookmarked() = manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED /** * Whether the display only unread filter is enabled. */ - fun onlyUnread(): Boolean { - return manga.readFilter == Manga.SHOW_UNREAD - } + fun onlyUnread() = manga.readFilter == Manga.SHOW_UNREAD /** * Whether the display only read filter is enabled. */ - fun onlyRead(): Boolean { - return manga.readFilter == Manga.SHOW_READ - } + fun onlyRead() = manga.readFilter == Manga.SHOW_READ /** * Whether the sorting method is descending or ascending. */ - fun sortDescending(): Boolean { - return manga.sortDescending() - } + fun sortDescending() = manga.sortDescending(globalSort()) /** * Applies the view filters to the list of chapters obtained from the database. @@ -442,8 +433,16 @@ class MangaDetailsPresenter( /** * Sets the sorting order and requests an UI update. */ - fun setSortOrder(desend: Boolean) { - manga.setChapterOrder(if (desend) Manga.SORT_ASC else Manga.SORT_DESC) + fun setSortOrder(descend: Boolean) { + manga.setChapterOrder(if (descend) Manga.SORT_DESC else Manga.SORT_ASC) + asyncUpdateMangaAndChapters() + } + + fun globalSort() = preferences.chaptersDescAsDefault().getOrDefault() + + fun setGlobalChapterSort(descend: Boolean) { + preferences.chaptersDescAsDefault().set(descend) + manga.setSortToGlobal() asyncUpdateMangaAndChapters() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt index 015ab6c38f..973033eaeb 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaHeaderHolder.kt @@ -50,9 +50,7 @@ class MangaHeaderHolder( manga_genres_tags.setOnTagClickListener { adapter.delegate.tagClicked(it) } - filter_button.setOnClickListener { adapter.delegate.showChapterFilter() } - filters_text.setOnClickListener { adapter.delegate.showChapterFilter() } - chapters_title.setOnClickListener { adapter.delegate.showChapterFilter() } + chapter_layout.setOnClickListener { adapter.delegate.showChapterFilter() } webview_button.setOnClickListener { adapter.delegate.openInWebView() } share_button.setOnClickListener { adapter.delegate.prepareToShareManga() } favorite_button.setOnClickListener { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSortBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSortBottomSheet.kt index 0305663cf5..aa78246a79 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSortBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersSortBottomSheet.kt @@ -10,8 +10,10 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.ui.manga.MangaDetailsController import eu.kanade.tachiyomi.util.system.dpToPx +import eu.kanade.tachiyomi.util.view.invisible import eu.kanade.tachiyomi.util.view.setBottomEdge import eu.kanade.tachiyomi.util.view.setEdgeToEdge +import eu.kanade.tachiyomi.util.view.visInvisIf import eu.kanade.tachiyomi.util.view.visibleIf import kotlinx.android.synthetic.main.chapter_sort_bottom_sheet.* @@ -84,16 +86,25 @@ class ChaptersSortBottomSheet(controller: MangaDetailsController) : BottomSheetD show_all.isChecked = !(show_read.isChecked || show_unread.isChecked || show_download.isChecked || show_bookmark.isChecked) - sort_group.check(if (presenter.manga.sortDescending()) R.id.sort_newest else + var defPref = presenter.globalSort() + sort_group.check(if (presenter.manga.sortDescending(defPref)) R.id.sort_newest else R.id.sort_oldest) hide_titles.isChecked = presenter.manga.displayMode != Manga.DISPLAY_NAME sort_method_group.check(if (presenter.manga.sorting == Manga.SORTING_SOURCE) R.id.sort_by_source else R.id.sort_by_number) + set_as_default_sort.visInvisIf(defPref != presenter.manga.sortDescending()) sort_group.setOnCheckedChangeListener { _, checkedId -> - presenter.setSortOrder(checkedId == R.id.sort_oldest) - dismiss() + presenter.setSortOrder(checkedId == R.id.sort_newest) + set_as_default_sort.visInvisIf(defPref != presenter.manga.sortDescending()) + } + + set_as_default_sort.setOnClickListener { + val desc = sort_group.checkedRadioButtonId == R.id.sort_newest + presenter.setGlobalChapterSort(desc) + defPref = desc + set_as_default_sort.invisible() } sort_method_group.setOnCheckedChangeListener { _, checkedId -> 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 50edcb5418..d0e65ad6a4 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 @@ -138,6 +138,10 @@ inline fun View.visibleIf(show: Boolean) { visibility = if (show) View.VISIBLE else View.GONE } +inline fun View.visInvisIf(show: Boolean) { + visibility = if (show) View.VISIBLE else View.INVISIBLE +} + /** * Returns a TextDrawable determined by input * @@ -354,10 +358,18 @@ fun Controller.scrollViewWith( if (router?.backstack?.lastOrNull() ?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activity!!.appbar.height > 0 ) { - activity!!.appbar.y -= dy - activity!!.appbar.y = clamp( - activity!!.appbar.y, -activity!!.appbar.height.toFloat(), 0f - ) + if (!recycler.canScrollVertically(-1)) { + val shortAnimationDuration = resources?.getInteger( + android.R.integer.config_shortAnimTime + ) ?: 0 + activity!!.appbar.animate().y(0f).setDuration(shortAnimationDuration.toLong()) + .start() + } else { + activity!!.appbar.y -= dy + activity!!.appbar.y = clamp( + activity!!.appbar.y, -activity!!.appbar.height.toFloat(), 0f + ) + } } } diff --git a/app/src/main/res/drawable/fast_scroll_background.xml b/app/src/main/res/drawable/fast_scroll_background.xml index a7d6ae84cd..3f5fb0f8f0 100644 --- a/app/src/main/res/drawable/fast_scroll_background.xml +++ b/app/src/main/res/drawable/fast_scroll_background.xml @@ -1,7 +1,7 @@ diff --git a/app/src/main/res/layout/chapter_sort_bottom_sheet.xml b/app/src/main/res/layout/chapter_sort_bottom_sheet.xml index 6e5fbe1036..eebe4bf885 100644 --- a/app/src/main/res/layout/chapter_sort_bottom_sheet.xml +++ b/app/src/main/res/layout/chapter_sort_bottom_sheet.xml @@ -20,13 +20,26 @@ android:paddingTop="12dp" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"> - + android:orientation="horizontal" + android:layout_height="wrap_content"> + + + + + diff --git a/app/src/main/res/layout/manga_header_item.xml b/app/src/main/res/layout/manga_header_item.xml index 7807c1af40..05e38550aa 100644 --- a/app/src/main/res/layout/manga_header_item.xml +++ b/app/src/main/res/layout/manga_header_item.xml @@ -10,11 +10,11 @@ android:id="@+id/true_backdrop" android:layout_width="0dp" android:layout_height="0dp" - app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="@id/bottom_line" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHeight_min="200dp" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintBottom_toBottomOf="@id/bottom_line" + app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" tools:background="@color/material_red_400" /> @@ -42,8 +42,8 @@ android:layout_width="match_parent" android:layout_height="0dp" android:background="?android:attr/colorBackground" - app:layout_constraintTop_toBottomOf="@id/backdrop_gradient" - app:layout_constraintBottom_toBottomOf="parent"/> + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintTop_toBottomOf="@id/backdrop_gradient" /> @@ -183,10 +183,10 @@ android:layout_gravity="center" android:layout_marginStart="6dp" android:layout_marginEnd="6dp" - android:tooltipText="@string/action_open_in_web_view" - android:padding="5dp" android:contentDescription="@string/action_open_in_web_view" - android:src="@drawable/ic_open_in_webview_white_24dp" /> + android:padding="5dp" + android:src="@drawable/ic_open_in_webview_white_24dp" + android:tooltipText="@string/action_open_in_web_view" /> + android:padding="5dp" + android:src="@drawable/ic_share_white_24dp" + android:tooltipText="@string/action_share" /> + app:layout_constraintTop_toBottomOf="@id/manga_summary" /> + app:layout_constraintTop_toBottomOf="@id/manga_summary" + tools:layout_height="100dp" + tools:visibility="visible" /> + app:rippleColor="@null" + tools:visibility="visible" /> - - - + android:background="?selectable_list_drawable" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/start_reading_button"> - + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de08ff1982..65856f1c1a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,6 +45,7 @@ Filter + Sort & Filter Change sources Display options Downloaded @@ -633,6 +634,7 @@ Custom filter Set as cover + Set as default for all Cover updated Page: %1$d