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
This commit is contained in:
Jay 2020-04-04 16:11:00 -04:00
parent 58d416d16c
commit 73373cab56
10 changed files with 177 additions and 108 deletions

View File

@ -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<SourceManager>().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

View File

@ -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)

View File

@ -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()
}

View File

@ -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 {

View File

@ -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 ->

View File

@ -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
)
}
}
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="4dp"
android:left="0dp"
android:right="4dp"
android:bottom="4dp"
android:top="4dp">

View File

@ -20,13 +20,26 @@
android:paddingTop="12dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.MaterialComponents.Headline6"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/action_sort" />
android:orientation="horizontal"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="12dp"
android:text="@string/action_sort" />
<com.google.android.material.button.MaterialButton
android:id="@+id/set_as_default_sort"
style="@style/Theme.Widget.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/set_as_default" />
</LinearLayout>
<RadioGroup
android:id="@+id/sort_group"
@ -39,16 +52,16 @@
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/sort_newest"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/newest_first" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/sort_oldest"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:text="@string/oldest_first" />
</RadioGroup>

View File

@ -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" />
<View
android:id="@+id/top_view"
@ -59,11 +59,11 @@
android:id="@+id/cover_card"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="16dp"
app:layout_constraintTop_toBottomOf="@id/top_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/top_view"
app:layout_constraintVertical_bias="1.0">
<ImageView
@ -72,9 +72,9 @@
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:clickable="true"
android:contentDescription="@string/description_cover"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:contentDescription="@string/description_cover"
android:maxHeight="300dp"
tools:background="@color/material_grey_700"
tools:src="@mipmap/ic_launcher" />
@ -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" />
<ImageView
android:id="@+id/share_button"
@ -196,10 +196,10 @@
android:layout_gravity="center"
android:layout_marginStart="0dp"
android:layout_marginEnd="6dp"
android:tooltipText="@string/action_share"
android:padding="5dp"
android:contentDescription="@string/action_share"
android:src="@drawable/ic_share_white_24dp" />
android:padding="5dp"
android:src="@drawable/ic_share_white_24dp"
android:tooltipText="@string/action_share" />
</LinearLayout>
<com.google.android.material.textview.MaterialTextView
@ -224,16 +224,16 @@
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:clickable="true"
android:focusable="true"
android:layout_marginEnd="16dp"
android:maxLines="3"
android:textIsSelectable="false"
app:layout_constraintBottom_toTopOf="@id/manga_genres_tags"
app:layout_constraintEnd_toEndOf="parent"
tools:maxLines="10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/manga_summary_label"
tools:maxLines="10"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." />
<View
@ -261,18 +261,18 @@
android:layout_width="1dp"
android:layout_height="15sp"
app:layout_constraintEnd_toEndOf="@id/manga_summary"
app:layout_constraintTop_toBottomOf="@id/manga_summary"/>
app:layout_constraintTop_toBottomOf="@id/manga_summary" />
<com.google.android.material.button.MaterialButton
android:id="@+id/more_button"
style="@style/Theme.Widget.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/more"
android:layout_marginEnd="8dp"
android:text="@string/more"
android:textAlignment="textEnd"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/more_guide"
app:layout_constraintEnd_toEndOf="parent"
app:rippleColor="@null" />
<androidx.constraintlayout.widget.Group
@ -297,8 +297,6 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:visibility="gone"
tools:visibility="visible"
tools:layout_height="100dp"
app:atg_backgroundColor="@android:color/transparent"
app:atg_borderColor="@color/md_blue_A400"
app:atg_borderStrokeWidth="1dp"
@ -307,81 +305,97 @@
app:layout_constraintBottom_toTopOf="@id/less_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/manga_summary" />
app:layout_constraintTop_toBottomOf="@id/manga_summary"
tools:layout_height="100dp"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
android:id="@+id/less_button"
style="@style/Theme.Widget.Button.TextButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/less"
android:visibility="gone"
tools:visibility="visible"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="@string/less"
android:textAlignment="textEnd"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/start_reading_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/manga_genres_tags"
app:rippleColor="@null" />
app:rippleColor="@null"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
android:id="@+id/start_reading_button"
style="@style/Theme.Widget.Button.Primary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:text="@string/start_reading"
app:layout_constraintBottom_toTopOf="@id/chapters_title"
app:layout_constraintBottom_toTopOf="@id/chapter_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/less_button"
tools:text="Continue Reading Chapter 17.1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/chapters_title"
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="wrap_content"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/chapter_layout"
android:layout_width="match_parent"
android:layout_marginTop="12dp"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:layout_marginBottom="12dp"
android:maxLines="1"
android:text="@string/chapters"
android:textSize="17sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/filters_text"
app:layout_constraintStart_toStartOf="@id/cover_card"
app:layout_constraintTop_toBottomOf="@id/start_reading_button" />
<ImageView
android:id="@+id/filter_button"
style="@style/Theme.Widget.CustomImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:padding="5dp"
android:tooltipText="@string/action_filter"
android:src="@drawable/ic_filter_list_white_24dp"
app:layout_constraintBottom_toBottomOf="@id/chapters_title"
android:tooltipText="@string/action_sort_and_filter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/chapters_title" />
android:background="?selectable_list_drawable"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/start_reading_button">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/filters_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="6dp"
android:maxLines="2"
android:padding="5dp"
android:textColor="?android:textColorHint"
android:textAlignment="textEnd"
app:layout_constraintBottom_toBottomOf="@id/filter_button"
app:layout_constraintEnd_toStartOf="@id/filter_button"
app:layout_constraintStart_toEndOf="@+id/chapters_title"
app:layout_constraintTop_toTopOf="@id/filter_button"
tools:text="Read, Unread, Bookmarked, Downloaded, All" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/chapters_title"
style="@style/TextAppearance.MaterialComponents.Headline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:maxLines="1"
android:text="@string/chapters"
android:textSize="17sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/filters_text"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/filter_button"
android:tint="?colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="9dp"
android:background="@null"
android:padding="5dp"
android:src="@drawable/ic_filter_list_white_24dp"
app:layout_constraintBottom_toBottomOf="@id/chapters_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/chapters_title" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/filters_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="6dp"
android:maxLines="2"
android:padding="5dp"
android:textAlignment="textEnd"
android:textColor="?android:textColorHint"
app:layout_constraintBottom_toBottomOf="@id/filter_button"
app:layout_constraintEnd_toStartOf="@id/filter_button"
app:layout_constraintStart_toEndOf="@+id/chapters_title"
app:layout_constraintTop_toTopOf="@id/filter_button"
app:layout_constraintBaseline_toBaselineOf="@id/chapters_title"
tools:text="Read, Unread, Bookmarked, Downloaded, All" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -45,6 +45,7 @@
<!-- Actions -->
<string name="action_filter">Filter</string>
<string name="action_sort_and_filter">Sort &amp; Filter</string>
<string name="action_change_sources">Change sources</string>
<string name="action_view_options">Display options</string>
<string name="action_filter_downloaded">Downloaded</string>
@ -633,6 +634,7 @@
<!-- Reader activity -->
<string name="custom_filter">Custom filter</string>
<string name="set_as_cover">Set as cover</string>
<string name="set_as_default">Set as default for all</string>
<string name="cover_updated">Cover updated</string>
<string name="chapter_progress">Page: %1$d</string>
<plurals name="pages_left">