Add "Started" library filter and library update restriction (#6382)

* Add chapter read count to library manga

Co-Authored-By: Jays2Kings <jays@outlook.com>

* Add "Started" library filter and library update restriction

* Update Filter when its changed

* Add back accidentally removed stuff.

* Update..

* Change variable names

* Change Variable name where I missed

Co-authored-by: Jays2Kings <jays@outlook.com>
(cherry picked from commit f18d161eaf54c9d9f74bf412447e15216f1ee1dc)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/resolvers/LibraryMangaGetResolver.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/tables/MangaTable.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibrarySettingsSheet.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt
This commit is contained in:
FourTOne5 2022-02-13 21:42:28 +06:00 committed by Jobobby04
parent 3b56bcfbba
commit a12758579d
14 changed files with 92 additions and 79 deletions

View File

@ -2,7 +2,14 @@ package eu.kanade.tachiyomi.data.database.models
class LibraryManga : MangaImpl() {
var unread: Int = 0
var unreadCount: Int = 0
var readCount: Int = 0
val totalChapters
get() = readCount + unreadCount
val hasStarted
get() = readCount > 0
var category: Int = 0

View File

@ -75,23 +75,23 @@ fun getReadMangaNotInLibraryQuery() =
"""
/**
* Query to get the manga from the library, with their categories and unread count.
* Query to get the manga from the library, with their categories, read and unread count.
*/
val libraryQuery =
"""
SELECT M.*, COALESCE(MC.${MangaCategory.COL_CATEGORY_ID}, 0) AS ${Manga.COL_CATEGORY}
FROM (
SELECT ${Manga.TABLE}.*, COALESCE(C.unread, 0) AS ${Manga.COL_UNREAD}, COALESCE(R.read, 0) AS ${Manga.COL_READ}
SELECT ${Manga.TABLE}.*, COALESCE(C.unreadCount, 0) AS ${Manga.COMPUTED_COL_UNREAD_COUNT}, COALESCE(R.readCount, 0) AS ${Manga.COMPUTED_COL_READ_COUNT}
FROM ${Manga.TABLE}
LEFT JOIN (
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}, COUNT(*) AS unread
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}, COUNT(*) AS unreadCount
FROM ${Chapter.TABLE}
WHERE ${Chapter.COL_READ} = 0
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
) AS C
ON ${Manga.TABLE}.${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID}
LEFT JOIN (
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS read
SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS readCount
FROM ${Chapter.TABLE}
WHERE ${Chapter.COL_READ} = 1
GROUP BY ${Chapter.COL_MANGA_ID}
@ -100,10 +100,10 @@ val libraryQuery =
WHERE ${Manga.COL_FAVORITE} = 1 AND ${Manga.COL_SOURCE} <> $MERGED_SOURCE_ID
GROUP BY ${Manga.TABLE}.${Manga.COL_ID}
UNION
SELECT ${Manga.TABLE}.*, COALESCE(C.unread, 0) AS ${Manga.COL_UNREAD}, COALESCE(R.read, 0) AS ${Manga.COL_READ}
SELECT ${Manga.TABLE}.*, COALESCE(C.unreadCount, 0) AS ${Manga.COMPUTED_COL_UNREAD_COUNT}, COALESCE(R.readCount, 0) AS ${Manga.COMPUTED_COL_READ_COUNT}
FROM ${Manga.TABLE}
LEFT JOIN (
SELECT ${Merged.TABLE}.${Merged.COL_MERGE_ID}, COUNT(*) as unread
SELECT ${Merged.TABLE}.${Merged.COL_MERGE_ID}, COUNT(*) as unreadCount
FROM ${Merged.TABLE}
JOIN ${Chapter.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ${Merged.TABLE}.${Merged.COL_MANGA_ID}
@ -112,7 +112,7 @@ val libraryQuery =
) AS C
ON ${Manga.TABLE}.${Manga.COL_ID} = C.${Merged.COL_MERGE_ID}
LEFT JOIN (
SELECT ${Merged.TABLE}.${Merged.COL_MERGE_ID}, COUNT(*) as read
SELECT ${Merged.TABLE}.${Merged.COL_MERGE_ID}, COUNT(*) as readCount
FROM ${Merged.TABLE}
JOIN ${Chapter.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = ${Merged.TABLE}.${Merged.COL_MANGA_ID}

View File

@ -16,11 +16,9 @@ class LibraryMangaGetResolver : DefaultGetResolver<LibraryManga>(), BaseMangaGet
val manga = LibraryManga()
mapBaseFromCursor(manga, cursor)
manga.unread = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COL_UNREAD))
manga.unreadCount = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COMPUTED_COL_UNREAD_COUNT))
manga.category = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COL_CATEGORY))
// SY -->
manga.read = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COL_READ))
// SY <--
manga.readCount = cursor.getInt(cursor.getColumnIndexOrThrow(MangaTable.COMPUTED_COL_READ_COUNT))
return manga
}

View File

@ -39,11 +39,7 @@ object MangaTable {
const val COL_CHAPTER_FLAGS = "chapter_flags"
const val COL_UNREAD = "unread"
// SY ->>
const val COL_READ = "read"
// SY -->
const val COL_FILTERED_SCANLATORS = "filtered_scanlators"
// SY <--
@ -51,6 +47,11 @@ object MangaTable {
const val COL_COVER_LAST_MODIFIED = "cover_last_modified"
// Not an actual value but computed when created
const val COMPUTED_COL_UNREAD_COUNT = "unread_count"
const val COMPUTED_COL_READ_COUNT = "read_count"
val createTableQuery: String
get() =
"""CREATE TABLE $TABLE(

View File

@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.MANGA_FULLY_READ
import eu.kanade.tachiyomi.data.preference.MANGA_ONGOING
import eu.kanade.tachiyomi.data.preference.MANGA_STARTED
import eu.kanade.tachiyomi.data.preference.PreferenceValues.GroupLibraryMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.EnhancedTrackService
@ -353,7 +354,14 @@ class LibraryUpdateService(
listToUpdate = listToUpdate.filterNot { it.status == SManga.COMPLETED }
}
if (MANGA_FULLY_READ in restrictions) {
listToUpdate = listToUpdate.filter { it.unread == 0 }
listToUpdate = listToUpdate.filter { it.unreadCount == 0 }
}
if (MANGA_STARTED in restrictions) {
listToUpdate = listToUpdate.filter { manga ->
// If the manga has 0 chapters you can't actually start reading it
if (manga.totalChapters == 0) true
else manga.hasStarted
}
}
}

View File

@ -31,12 +31,12 @@ object PreferenceKeys {
const val filterUnread = "pref_filter_library_unread"
const val filterStarted = "pref_filter_library_started"
const val filterCompleted = "pref_filter_library_completed"
const val filterTracked = "pref_filter_library_tracked"
const val filterStarted = "pref_filter_library_started"
const val filterLewd = "pref_filter_library_lewd"
const val librarySortingMode = "library_sorting_mode"

View File

@ -7,6 +7,7 @@ const val DEVICE_CHARGING = "ac"
const val MANGA_ONGOING = "manga_ongoing"
const val MANGA_FULLY_READ = "manga_fully_read"
const val MANGA_STARTED = "manga_started"
/**
* This class stores the values for the preferences in the application.

View File

@ -231,7 +231,7 @@ class PreferencesHelper(val context: Context) {
fun libraryUpdateInterval() = flowPrefs.getInt("pref_library_update_interval_key", 24)
fun libraryUpdateDeviceRestriction() = flowPrefs.getStringSet("library_update_restriction", setOf(DEVICE_ONLY_ON_WIFI))
fun libraryUpdateMangaRestriction() = flowPrefs.getStringSet("library_update_manga_restriction", setOf(MANGA_FULLY_READ, MANGA_ONGOING))
fun libraryUpdateMangaRestriction() = flowPrefs.getStringSet("library_update_manga_restriction", setOf(MANGA_FULLY_READ, MANGA_ONGOING, MANGA_STARTED))
fun showUpdatesNavBadge() = flowPrefs.getBoolean("library_update_show_tab_badge", false)
fun unreadUpdatesCount() = flowPrefs.getInt("library_unread_updates_count", 0)
@ -259,12 +259,12 @@ class PreferencesHelper(val context: Context) {
fun filterUnread() = flowPrefs.getInt(Keys.filterUnread, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterStarted() = flowPrefs.getInt(Keys.filterStarted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterCompleted() = flowPrefs.getInt(Keys.filterCompleted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterTracking(name: Int) = flowPrefs.getInt("${Keys.filterTracked}_$name", ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterStarted() = flowPrefs.getInt(Keys.filterStarted, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun filterLewd() = flowPrefs.getInt(Keys.filterLewd, ExtendedNavigationView.Item.TriStateGroup.State.IGNORE.value)
fun librarySortingMode() = flowPrefs.getEnum(Keys.librarySortingMode, SortModeSetting.ALPHABETICAL)

View File

@ -77,7 +77,7 @@ class LibraryComfortableGridHolder(
binding.badges.localText.isVisible = item.isLocal
// SY -->
binding.playLayout.isVisible = (item.manga.unread > 0 && item.startReadingButton)
binding.playLayout.isVisible = (item.manga.unreadCount > 0 && item.startReadingButton)
// SY <--
// For rounded corners

View File

@ -91,7 +91,7 @@ class LibraryCompactGridHolder(
binding.playLayout.updateLayoutParams<FrameLayout.LayoutParams> {
updateMargins(top = topMargin)
}
binding.playLayout.isVisible = (item.manga.unread > 0 && item.startReadingButton)
binding.playLayout.isVisible = (item.manga.unreadCount > 0 && item.startReadingButton)
// SY <--
// For rounded corners

View File

@ -164,6 +164,7 @@ class LibraryPresenter(
val downloadedOnly = preferences.downloadedOnly().get()
val filterDownloaded = preferences.filterDownloaded().get()
val filterUnread = preferences.filterUnread().get()
val filterStarted = preferences.filterStarted().get()
val filterCompleted = preferences.filterCompleted().get()
val loggedInServices = trackManager.services.filter { trackService -> trackService.isLogged }
.associate { trackService ->
@ -171,26 +172,9 @@ class LibraryPresenter(
}
val isNotAnyLoggedIn = !loggedInServices.values.any()
// SY -->
val filterStarted = preferences.filterStarted().get()
val filterLewd = preferences.filterLewd().get()
// SY <--
val filterFnUnread: (LibraryItem) -> Boolean = unread@{ item ->
if (filterUnread == State.IGNORE.value) return@unread true
val isUnread = item.manga.unread != 0
return@unread if (filterUnread == State.INCLUDE.value) isUnread
else !isUnread
}
val filterFnCompleted: (LibraryItem) -> Boolean = completed@{ item ->
if (filterCompleted == State.IGNORE.value) return@completed true
val isCompleted = item.manga.status == SManga.COMPLETED
return@completed if (filterCompleted == State.INCLUDE.value) isCompleted
else !isCompleted
}
val filterFnDownloaded: (LibraryItem) -> Boolean = downloaded@{ item ->
if (!downloadedOnly && filterDownloaded == State.IGNORE.value) return@downloaded true
val isDownloaded = when {
@ -203,6 +187,30 @@ class LibraryPresenter(
else !isDownloaded
}
val filterFnUnread: (LibraryItem) -> Boolean = unread@{ item ->
if (filterUnread == State.IGNORE.value) return@unread true
val isUnread = item.manga.unreadCount != 0
return@unread if (filterUnread == State.INCLUDE.value) isUnread
else !isUnread
}
val filterFnStarted: (LibraryItem) -> Boolean = started@{ item ->
if (filterStarted == State.IGNORE.value) return@started true
val hasStarted = item.manga.hasStarted
return@started if (filterStarted == State.INCLUDE.value) hasStarted
else !hasStarted
}
val filterFnCompleted: (LibraryItem) -> Boolean = completed@{ item ->
if (filterCompleted == State.IGNORE.value) return@completed true
val isCompleted = item.manga.status == SManga.COMPLETED
return@completed if (filterCompleted == State.INCLUDE.value) isCompleted
else !isCompleted
}
val filterFnTracking: (LibraryItem) -> Boolean = tracking@{ item ->
if (isNotAnyLoggedIn) return@tracking true
@ -228,14 +236,6 @@ class LibraryPresenter(
}
// SY -->
val filterFnStarted: (LibraryItem) -> Boolean = started@{ item ->
if (filterStarted == State.IGNORE.value) return@started true
val hasRead = item.manga.read != 0
return@started if (filterStarted == State.INCLUDE.value) hasRead
else !hasRead
}
val filterFnLewd: (LibraryItem) -> Boolean = lewd@{ item ->
if (filterLewd == State.IGNORE.value) return@lewd true
val isLewd = item.manga.isLewd()
@ -247,12 +247,12 @@ class LibraryPresenter(
val filterFn: (LibraryItem) -> Boolean = filter@{ item ->
return@filter !(
!filterFnUnread(item) ||
!filterFnDownloaded(item) ||
!filterFnUnread(item) ||
!filterFnStarted(item) ||
!filterFnCompleted(item) ||
!filterFnDownloaded(item) ||
!filterFnTracking(item) ||
// SY -->
!filterFnStarted(item) ||
!filterFnLewd(item)
// SY <--
)
@ -302,7 +302,7 @@ class LibraryPresenter(
}
item.unreadCount = if (showUnreadBadges) {
item.manga.unread
item.manga.unreadCount
} else {
// Unset unread count if not enabled
-1
@ -335,10 +335,6 @@ class LibraryPresenter(
var counter = 0
db.getLastReadManga().executeAsBlocking().associate { it.id!! to counter++ }
}
val totalChapterManga by lazy {
var counter = 0
db.getTotalChapterManga().executeAsBlocking().associate { it.id!! to counter++ }
}
val latestChapterManga by lazy {
var counter = 0
db.getLatestChapterManga().executeAsBlocking().associate { it.id!! to counter++ }
@ -367,8 +363,8 @@ class LibraryPresenter(
(category.id ?: 0) to SortModeSetting.get(preferences, category)
}
val defaultSortAscending = SortDirectionSetting.get(preferences, null)
val sortAscending = categories.associate { category ->
val defaultSortDirection = SortDirectionSetting.get(preferences, null)
val sortDirections = categories.associate { category ->
(category.id ?: 0) to SortDirectionSetting.get(preferences, category)
}
@ -383,9 +379,9 @@ class LibraryPresenter(
defaultSortingMode
}
val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) {
sortAscending[i1.manga.category] ?: defaultSortAscending
sortDirections[i1.manga.category] ?: defaultSortDirection
} else {
defaultSortAscending
defaultSortDirection
} == SortDirectionSetting.ASCENDING
when (sortingMode) {
@ -401,15 +397,13 @@ class LibraryPresenter(
SortModeSetting.LAST_CHECKED -> i2.manga.last_update.compareTo(i1.manga.last_update)
SortModeSetting.UNREAD -> when {
// Ensure unread content comes first
i1.manga.unread == i2.manga.unread -> 0
i1.manga.unread == 0 -> if (sortAscending) 1 else -1
i2.manga.unread == 0 -> if (sortAscending) -1 else 1
else -> i1.manga.unread.compareTo(i2.manga.unread)
i1.manga.unreadCount == i2.manga.unreadCount -> 0
i1.manga.unreadCount == 0 -> if (sortAscending) 1 else -1
i2.manga.unreadCount == 0 -> if (sortAscending) -1 else 1
else -> i1.manga.unreadCount.compareTo(i2.manga.unreadCount)
}
SortModeSetting.TOTAL_CHAPTERS -> {
val manga1TotalChapter = totalChapterManga[i1.manga.id!!] ?: 0
val mange2TotalChapter = totalChapterManga[i2.manga.id!!] ?: 0
manga1TotalChapter.compareTo(mange2TotalChapter)
i1.manga.totalChapters.compareTo(i2.manga.totalChapters)
}
SortModeSetting.LATEST_CHAPTER -> {
val manga1latestChapter = latestChapterManga[i1.manga.id!!]
@ -441,9 +435,9 @@ class LibraryPresenter(
return map.mapValues { entry ->
val sortAscending = if (groupType == LibraryGroup.BY_DEFAULT) {
sortAscending[entry.key] ?: defaultSortAscending
sortDirections[entry.key] ?: defaultSortDirection
} else {
defaultSortAscending
defaultSortDirection
} == SortDirectionSetting.ASCENDING
val comparator = if (sortAscending) {

View File

@ -95,11 +95,11 @@ class LibrarySettingsSheet(
private val downloaded = Item.TriStateGroup(R.string.action_filter_downloaded, this)
private val unread = Item.TriStateGroup(R.string.action_filter_unread, this)
private val started = Item.TriStateGroup(R.string.action_filter_started, this)
private val completed = Item.TriStateGroup(R.string.completed, this)
private val trackFilters: Map<Int, Item.TriStateGroup>
// SY -->
private val started = Item.TriStateGroup(R.string.started, this)
private val lewd = Item.TriStateGroup(R.string.lewd, this)
// SY <--
@ -114,7 +114,7 @@ class LibrarySettingsSheet(
trackFilters = services.associate { service ->
Pair(service.id, Item.TriStateGroup(getServiceResId(service, size), this))
}
val list: MutableList<Item> = mutableListOf(downloaded, unread, completed, started, lewd)
val list: MutableList<Item> = mutableListOf(downloaded, unread, started, completed, lewd)
if (size > 1) list.add(Item.Header(R.string.action_filter_tracked))
list.addAll(trackFilters.values)
items = list
@ -133,6 +133,7 @@ class LibrarySettingsSheet(
downloaded.state = preferences.filterDownloaded().get()
}
unread.state = preferences.filterUnread().get()
started.state = preferences.filterStarted().get()
completed.state = preferences.filterCompleted().get()
trackFilters.forEach { trackFilter ->
@ -140,7 +141,6 @@ class LibrarySettingsSheet(
}
// SY -->
started.state = preferences.filterStarted().get()
lewd.state = preferences.filterLewd().get()
// SY <--
}
@ -157,9 +157,9 @@ class LibrarySettingsSheet(
when (item) {
downloaded -> preferences.filterDownloaded().set(newState)
unread -> preferences.filterUnread().set(newState)
started -> preferences.filterStarted().set(newState)
completed -> preferences.filterCompleted().set(newState)
// SY -->
started -> preferences.filterStarted().set(newState)
lewd -> preferences.filterLewd().set(newState)
// SY <--
else -> {

View File

@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING
import eu.kanade.tachiyomi.data.preference.DEVICE_ONLY_ON_WIFI
import eu.kanade.tachiyomi.data.preference.MANGA_FULLY_READ
import eu.kanade.tachiyomi.data.preference.MANGA_ONGOING
import eu.kanade.tachiyomi.data.preference.MANGA_STARTED
import eu.kanade.tachiyomi.data.preference.PreferenceValues.GroupLibraryMode
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.track.TrackManager
@ -221,16 +222,16 @@ class SettingsLibraryController : SettingsController() {
multiSelectListPreference {
bindTo(preferences.libraryUpdateMangaRestriction())
titleRes = R.string.pref_library_update_manga_restriction
entriesRes = arrayOf(R.string.pref_update_only_completely_read, R.string.pref_update_only_non_completed)
entryValues = arrayOf(MANGA_FULLY_READ, MANGA_ONGOING)
entriesRes = arrayOf(R.string.pref_update_only_completely_read, R.string.pref_update_only_non_completed, R.string.pref_update_only_started)
entryValues = arrayOf(MANGA_FULLY_READ, MANGA_ONGOING, MANGA_STARTED)
fun updateSummary() {
val restrictions = preferences.libraryUpdateMangaRestriction().get()
.sorted()
val restrictions = preferences.libraryUpdateMangaRestriction().get().sorted()
.map {
when (it) {
MANGA_ONGOING -> context.getString(R.string.pref_update_only_non_completed)
MANGA_FULLY_READ -> context.getString(R.string.pref_update_only_completely_read)
MANGA_STARTED -> context.getString(R.string.pref_update_only_started)
else -> it
}
}

View File

@ -38,6 +38,7 @@
<string name="action_filter_bookmarked">Bookmarked</string>
<string name="action_filter_tracked">Tracked</string>
<string name="action_filter_unread">Unread</string>
<string name="action_filter_started">Started</string>
<string name="action_filter_empty">Remove filter</string>
<string name="action_sort_alpha">Alphabetically</string>
<string name="action_sort_count">Total manga</string>
@ -222,10 +223,12 @@
<string name="connected_to_wifi">Only on Wi-Fi</string>
<string name="charging">Charging</string>
<string name="restrictions">Restrictions: %s</string>
<string name="pref_library_update_manga_restriction">Library update restrictions</string>
<string name="only_update_restrictions">Only update: %s</string>
<string name="pref_update_only_completely_read">Completely read series</string>
<string name="pref_update_only_non_completed">Ongoing series</string>
<string name="pref_update_only_started">Started series</string>
<string name="pref_library_update_show_tab_badge">Show unread count on Updates icon</string>
<string name="pref_library_update_refresh_metadata">Automatically refresh metadata</string>
<string name="pref_library_update_refresh_metadata_summary">Check for new cover and details when updating library</string>