Implement scanlator filter (#8803)

* Implement scanlator filter

* Visual improvement to scanlator filter dialog

* Review changes + Bug fixes

Backup not containing filtered chapters and similar issue fix

* Review Changes + Fix SQL query

* Lint mamma mia

(cherry picked from commit b97aa235480e35b5514b7b1489b9d4413cea66d9)

# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/eu/kanade/presentation/manga/ChapterSettingsDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupCreator.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreenModel.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
#	data/src/main/java/tachiyomi/data/chapter/ChapterRepositoryImpl.kt
#	data/src/main/sqldelight/tachiyomi/migrations/23.sqm
#	data/src/main/sqldelight/tachiyomi/migrations/26.sqm
#	domain/src/main/java/tachiyomi/domain/history/interactor/GetNextChapters.kt
This commit is contained in:
AntsyLich
2023-11-05 21:34:35 +06:00
committed by Jobobby04
parent 94fa45597d
commit c8909961c0
48 changed files with 503 additions and 237 deletions
@@ -27,16 +27,3 @@ object UpdateStrategyColumnAdapter : ColumnAdapter<UpdateStrategy, Long> {
override fun encode(value: UpdateStrategy): Long = value.ordinal.toLong()
}
// SY -->
private const val LIST_OF_STRINGS_AND_SEPARATOR = " & "
object StringListAndColumnAdapter : ColumnAdapter<List<String>, String> {
override fun decode(databaseValue: String) =
if (databaseValue.isEmpty()) {
emptyList()
} else {
databaseValue.split(LIST_OF_STRINGS_AND_SEPARATOR)
}
override fun encode(value: List<String>) = value.joinToString(separator = LIST_OF_STRINGS_AND_SEPARATOR)
}
// SY <--
@@ -27,7 +27,7 @@ private val mapper = { cursor: SqlCursor ->
chapter_flags = cursor.getLong(15)!!,
cover_last_modified = cursor.getLong(16)!!,
date_added = cursor.getLong(17)!!,
filtered_scanlators = cursor.getString(18)?.let(StringListAndColumnAdapter::decode),
filtered_scanlators = null,
update_strategy = UpdateStrategyColumnAdapter.decode(cursor.getLong(19)!!),
calculate_interval = cursor.getLong(20)!!,
last_modified_at = cursor.getLong(21)!!,
@@ -71,8 +71,12 @@ class LibraryQuery(
coalesce(max(chapters.date_fetch), 0) AS fetchedAt,
sum(chapters.bookmark) AS bookmarkCount
FROM chapters
LEFT JOIN excluded_scanlators
ON chapters.manga_id = excluded_scanlators.manga_id
AND chapters.scanlator = excluded_scanlators.scanlator
LEFT JOIN history
ON chapters._id = history.chapter_id
WHERE excluded_scanlators.scanlator IS NULL
GROUP BY chapters.manga_id
) AS C
ON M._id = C.manga_id
@@ -106,10 +110,14 @@ class LibraryQuery(
coalesce(max(chapters.date_fetch), 0) AS fetchedAt,
sum(chapters.bookmark) AS bookmarkCount
FROM chapters
LEFT JOIN excluded_scanlators
ON chapters.manga_id = excluded_scanlators.manga_id
AND chapters.scanlator = excluded_scanlators.scanlator
LEFT JOIN history
ON chapters._id = history.chapter_id
LEFT JOIN merged as ME
ON ME.manga_id = chapters.manga_id
WHERE excluded_scanlators.scanlator IS NULL
GROUP BY ME.merge_id
) AS C
ON ME.merge_id = C.merge_id
@@ -2,6 +2,7 @@ package tachiyomi.data.chapter
import kotlinx.coroutines.flow.Flow
import logcat.LogPriority
import tachiyomi.core.util.lang.toLong
import tachiyomi.core.util.system.logcat
import tachiyomi.data.DatabaseHandler
import tachiyomi.domain.chapter.model.Chapter
@@ -76,8 +77,22 @@ class ChapterRepositoryImpl(
}
}
override suspend fun getChapterByMangaId(mangaId: Long): List<Chapter> {
return handler.awaitList { chaptersQueries.getChaptersByMangaId(mangaId, ChapterMapper::mapChapter) }
override suspend fun getChapterByMangaId(mangaId: Long, applyScanlatorFilter: Boolean): List<Chapter> {
return handler.awaitList {
chaptersQueries.getChaptersByMangaId(mangaId, applyScanlatorFilter.toLong(), ChapterMapper::mapChapter)
}
}
override suspend fun getScanlatorsByMangaId(mangaId: Long): List<String> {
return handler.awaitList {
chaptersQueries.getScanlatorsByMangaId(mangaId) { it.orEmpty() }
}
}
override fun getScanlatorsByMangaIdAsFlow(mangaId: Long): Flow<List<String>> {
return handler.subscribeToList {
chaptersQueries.getScanlatorsByMangaId(mangaId) { it.orEmpty() }
}
}
override suspend fun getBookmarkedChaptersByMangaId(mangaId: Long): List<Chapter> {
@@ -93,12 +108,9 @@ class ChapterRepositoryImpl(
return handler.awaitOneOrNull { chaptersQueries.getChapterById(id, ChapterMapper::mapChapter) }
}
override suspend fun getChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> {
override suspend fun getChapterByMangaIdAsFlow(mangaId: Long, applyScanlatorFilter: Boolean): Flow<List<Chapter>> {
return handler.subscribeToList {
chaptersQueries.getChaptersByMangaId(
mangaId,
ChapterMapper::mapChapter,
)
chaptersQueries.getChaptersByMangaId(mangaId, applyScanlatorFilter.toLong(), ChapterMapper::mapChapter)
}
}
@@ -117,13 +129,13 @@ class ChapterRepositoryImpl(
return handler.awaitList { chaptersQueries.getChapterByUrl(url, ChapterMapper::mapChapter) }
}
override suspend fun getMergedChapterByMangaId(mangaId: Long): List<Chapter> {
return handler.awaitList { chaptersQueries.getMergedChaptersByMangaId(mangaId, ChapterMapper::mapChapter) }
override suspend fun getMergedChapterByMangaId(mangaId: Long, applyScanlatorFilter: Boolean): List<Chapter> {
return handler.awaitList { chaptersQueries.getMergedChaptersByMangaId(mangaId, applyScanlatorFilter.toLong(), ChapterMapper::mapChapter) }
}
override suspend fun getMergedChapterByMangaIdAsFlow(mangaId: Long): Flow<List<Chapter>> {
override suspend fun getMergedChapterByMangaIdAsFlow(mangaId: Long, applyScanlatorFilter: Boolean): Flow<List<Chapter>> {
return handler.subscribeToList {
chaptersQueries.getMergedChaptersByMangaId(mangaId, ChapterMapper::mapChapter)
chaptersQueries.getMergedChaptersByMangaId(mangaId, applyScanlatorFilter.toLong(), ChapterMapper::mapChapter)
}
}
// SY <--
@@ -25,7 +25,10 @@ object MangaMapper {
chapterFlags: Long,
coverLastModified: Long,
dateAdded: Long,
filteredScanlators: List<String>?,
// SY -->
@Suppress("UNUSED_PARAMETER")
filteredScanlators: String?,
// SY <--
updateStrategy: UpdateStrategy,
calculateInterval: Long,
lastModifiedAt: Long,
@@ -53,9 +56,6 @@ object MangaMapper {
thumbnailUrl = thumbnailUrl,
updateStrategy = updateStrategy,
initialized = initialized,
// SY -->
filteredScanlators = filteredScanlators,
// SY <--
lastModifiedAt = lastModifiedAt,
favoriteModifiedAt = favoriteModifiedAt,
)
@@ -79,7 +79,10 @@ object MangaMapper {
chapterFlags: Long,
coverLastModified: Long,
dateAdded: Long,
filteredScanlators: List<String>?,
// SY -->
@Suppress("UNUSED_PARAMETER")
filteredScanlators: String?,
// SY <--
updateStrategy: UpdateStrategy,
calculateInterval: Long,
lastModifiedAt: Long,
@@ -112,7 +115,7 @@ object MangaMapper {
coverLastModified,
dateAdded,
// SY -->
filteredScanlators,
null,
// SY <--
updateStrategy,
calculateInterval,
@@ -150,7 +153,6 @@ object MangaMapper {
thumbnailUrl = libraryView.thumbnail_url,
updateStrategy = libraryView.update_strategy,
initialized = libraryView.initialized,
filteredScanlators = libraryView.filtered_scanlators,
fetchInterval = libraryView.calculate_interval.toInt(),
lastModifiedAt = libraryView.last_modified_at,
favoriteModifiedAt = libraryView.favorite_modified_at,
@@ -6,7 +6,6 @@ import logcat.LogPriority
import tachiyomi.core.util.system.logcat
import tachiyomi.data.AndroidDatabaseHandler
import tachiyomi.data.DatabaseHandler
import tachiyomi.data.StringListAndColumnAdapter
import tachiyomi.data.StringListColumnAdapter
import tachiyomi.data.UpdateStrategyColumnAdapter
import tachiyomi.domain.library.model.LibraryManga
@@ -119,9 +118,6 @@ class MangaRepositoryImpl(
chapterFlags = manga.chapterFlags,
coverLastModified = manga.coverLastModified,
dateAdded = manga.dateAdded,
// SY -->
filteredScanlators = manga.filteredScanlators,
// SY <--
updateStrategy = manga.updateStrategy,
)
mangasQueries.selectLastInsertedRowId()
@@ -170,9 +166,6 @@ class MangaRepositoryImpl(
chapterFlags = value.chapterFlags,
coverLastModified = value.coverLastModified,
dateAdded = value.dateAdded,
// SY -->
filteredScanlators = value.filteredScanlators?.let(StringListAndColumnAdapter::encode),
// SY <--
mangaId = value.id,
updateStrategy = value.updateStrategy?.let(UpdateStrategyColumnAdapter::encode),
)