mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-10 02:05:09 +01:00
Use the same logic in the mangadetails filter as the reader filter (#543)
* use the same chapter filter for the mangadetails and the reader presenter page * removed unused class * move volume detection logic to chapter utils
This commit is contained in:
parent
813a3c6e68
commit
7372109520
@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import uy.kohesive.injekt.api.InjektModule
|
import uy.kohesive.injekt.api.InjektModule
|
||||||
@ -48,6 +49,8 @@ class AppModule(val app: Application) : InjektModule {
|
|||||||
|
|
||||||
addSingletonFactory { Gson() }
|
addSingletonFactory { Gson() }
|
||||||
|
|
||||||
|
addSingletonFactory { ChapterFilter() }
|
||||||
|
|
||||||
// Asynchronously init expensive components for a faster cold start
|
// Asynchronously init expensive components for a faster cold start
|
||||||
|
|
||||||
GlobalScope.launch { get<PreferencesHelper>() }
|
GlobalScope.launch { get<PreferencesHelper>() }
|
||||||
|
@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterAdapter
|
import eu.kanade.tachiyomi.ui.manga.chapter.BaseChapterAdapter
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterUtil
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.text.DecimalFormatSymbols
|
import java.text.DecimalFormatSymbols
|
||||||
@ -26,7 +27,7 @@ class MangaDetailsAdapter(
|
|||||||
val presenter = controller.presenter
|
val presenter = controller.presenter
|
||||||
|
|
||||||
val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols()
|
val decimalFormat = DecimalFormat("#.###", DecimalFormatSymbols()
|
||||||
.apply { decimalSeparator = '.' })
|
.apply { decimalSeparator = '.' })
|
||||||
|
|
||||||
fun setChapters(items: List<ChapterItem>?) {
|
fun setChapters(items: List<ChapterItem>?) {
|
||||||
this.items = items ?: emptyList()
|
this.items = items ?: emptyList()
|
||||||
@ -46,8 +47,10 @@ class MangaDetailsAdapter(
|
|||||||
if (s.isNullOrBlank()) {
|
if (s.isNullOrBlank()) {
|
||||||
updateDataSet(items)
|
updateDataSet(items)
|
||||||
} else {
|
} else {
|
||||||
updateDataSet(items.filter { it.name.contains(s, true) ||
|
updateDataSet(items.filter {
|
||||||
it.scanlator?.contains(s, true) == true })
|
it.name.contains(s, true) ||
|
||||||
|
it.scanlator?.contains(s, true) == true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +67,7 @@ class MangaDetailsAdapter(
|
|||||||
getItem(position) as? ChapterItem ?: return recyclerView.context.getString(R.string.top)
|
getItem(position) as? ChapterItem ?: return recyclerView.context.getString(R.string.top)
|
||||||
return when (val scrollType = presenter.scrollType) {
|
return when (val scrollType = presenter.scrollType) {
|
||||||
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS -> {
|
MangaDetailsPresenter.MULTIPLE_VOLUMES, MangaDetailsPresenter.MULTIPLE_SEASONS -> {
|
||||||
val volume = presenter.getGroupNumber(chapter)
|
val volume = ChapterUtil.getGroupNumber(chapter)
|
||||||
if (volume != null) {
|
if (volume != null) {
|
||||||
recyclerView.context.getString(
|
recyclerView.context.getString(
|
||||||
if (scrollType == MangaDetailsPresenter.MULTIPLE_SEASONS) R.string.season_
|
if (scrollType == MangaDetailsPresenter.MULTIPLE_SEASONS) R.string.season_
|
||||||
|
@ -30,6 +30,8 @@ import eu.kanade.tachiyomi.source.model.SChapter
|
|||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterUtil
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.lang.trimOrNull
|
import eu.kanade.tachiyomi.util.lang.trimOrNull
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
@ -57,7 +59,8 @@ class MangaDetailsPresenter(
|
|||||||
val preferences: PreferencesHelper = Injekt.get(),
|
val preferences: PreferencesHelper = Injekt.get(),
|
||||||
val coverCache: CoverCache = Injekt.get(),
|
val coverCache: CoverCache = Injekt.get(),
|
||||||
private val db: DatabaseHelper = Injekt.get(),
|
private val db: DatabaseHelper = Injekt.get(),
|
||||||
private val downloadManager: DownloadManager = Injekt.get()
|
private val downloadManager: DownloadManager = Injekt.get(),
|
||||||
|
private val chapterFilter: ChapterFilter = Injekt.get()
|
||||||
) : DownloadQueue.DownloadListener, LibraryServiceListener {
|
) : DownloadQueue.DownloadListener, LibraryServiceListener {
|
||||||
|
|
||||||
private var scope = CoroutineScope(Job() + Dispatchers.Default)
|
private var scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||||
@ -68,8 +71,6 @@ class MangaDetailsPresenter(
|
|||||||
var hasRequested = false
|
var hasRequested = false
|
||||||
var isLoading = false
|
var isLoading = false
|
||||||
var scrollType = 0
|
var scrollType = 0
|
||||||
private val volumeRegex = Regex("""(vol|volume)\.? *([0-9]+)?""", RegexOption.IGNORE_CASE)
|
|
||||||
private val seasonRegex = Regex("""(Season |S)([0-9]+)?""")
|
|
||||||
|
|
||||||
private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLogged } }
|
private val loggedServices by lazy { Injekt.get<TrackManager>().services.filter { it.isLogged } }
|
||||||
private var tracks = emptyList<Track>()
|
private var tracks = emptyList<Track>()
|
||||||
@ -199,26 +200,6 @@ class MangaDetailsPresenter(
|
|||||||
controller.refreshAdapter()
|
controller.refreshAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the display only downloaded filter is enabled.
|
|
||||||
*/
|
|
||||||
fun onlyDownloaded() = manga.downloadedFilter == Manga.SHOW_DOWNLOADED
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the display only downloaded filter is enabled.
|
|
||||||
*/
|
|
||||||
fun onlyBookmarked() = manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the display only unread filter is enabled.
|
|
||||||
*/
|
|
||||||
fun onlyUnread() = manga.readFilter == Manga.SHOW_UNREAD
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the display only read filter is enabled.
|
|
||||||
*/
|
|
||||||
fun onlyRead() = manga.readFilter == Manga.SHOW_READ
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the sorting method is descending or ascending.
|
* Whether the sorting method is descending or ascending.
|
||||||
*/
|
*/
|
||||||
@ -232,18 +213,9 @@ class MangaDetailsPresenter(
|
|||||||
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
|
private fun applyChapterFilters(chapterList: List<ChapterItem>): List<ChapterItem> {
|
||||||
if (isLockedFromSearch)
|
if (isLockedFromSearch)
|
||||||
return chapterList
|
return chapterList
|
||||||
var chapters = chapterList
|
|
||||||
if (onlyUnread()) {
|
val chapters = chapterFilter.filterChapters(chapterList, manga) as List<ChapterItem>
|
||||||
chapters = chapters.filter { !it.read }
|
|
||||||
} else if (onlyRead()) {
|
|
||||||
chapters = chapters.filter { it.read }
|
|
||||||
}
|
|
||||||
if (onlyDownloaded()) {
|
|
||||||
chapters = chapters.filter { it.isDownloaded || it.manga.source == LocalSource.ID }
|
|
||||||
}
|
|
||||||
if (onlyBookmarked()) {
|
|
||||||
chapters = chapters.filter { it.bookmark }
|
|
||||||
}
|
|
||||||
val sortFunction: (Chapter, Chapter) -> Int = when (manga.sorting) {
|
val sortFunction: (Chapter, Chapter) -> Int = when (manga.sorting) {
|
||||||
Manga.SORTING_SOURCE -> when (sortDescending()) {
|
Manga.SORTING_SOURCE -> when (sortDescending()) {
|
||||||
true -> { c1, c2 -> c1.source_order.compareTo(c2.source_order) }
|
true -> { c1, c2 -> c1.source_order.compareTo(c2.source_order) }
|
||||||
@ -255,68 +227,19 @@ class MangaDetailsPresenter(
|
|||||||
}
|
}
|
||||||
else -> { c1, c2 -> c1.source_order.compareTo(c2.source_order) }
|
else -> { c1, c2 -> c1.source_order.compareTo(c2.source_order) }
|
||||||
}
|
}
|
||||||
chapters = chapters.sortedWith(Comparator(sortFunction))
|
|
||||||
getScrollType(chapters)
|
getScrollType(chapters)
|
||||||
return chapters
|
return chapters.sortedWith(Comparator(sortFunction))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getScrollType(chapters: List<ChapterItem>) {
|
private fun getScrollType(chapters: List<ChapterItem>) {
|
||||||
scrollType = when {
|
scrollType = when {
|
||||||
hasMultipleVolumes(chapters) -> MULTIPLE_VOLUMES
|
ChapterUtil.hasMultipleVolumes(chapters) -> MULTIPLE_VOLUMES
|
||||||
hasMultipleSeasons(chapters) -> MULTIPLE_SEASONS
|
ChapterUtil.hasMultipleSeasons(chapters) -> MULTIPLE_SEASONS
|
||||||
hasTensOfChapters(chapters) -> TENS_OF_CHAPTERS
|
ChapterUtil.hasTensOfChapters(chapters) -> TENS_OF_CHAPTERS
|
||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGroupNumber(chapter: ChapterItem): Int? {
|
|
||||||
val groups = volumeRegex.find(chapter.name)?.groups
|
|
||||||
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
|
||||||
val seasonGroups = seasonRegex.find(chapter.name)?.groups
|
|
||||||
if (seasonGroups != null) return seasonGroups[2]?.value?.toIntOrNull()
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getVolumeNumber(chapter: ChapterItem): Int? {
|
|
||||||
val groups = volumeRegex.find(chapter.name)?.groups
|
|
||||||
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSeasonNumber(chapter: ChapterItem): Int? {
|
|
||||||
val groups = seasonRegex.find(chapter.name)?.groups
|
|
||||||
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hasMultipleVolumes(chapters: List<ChapterItem>): Boolean {
|
|
||||||
val volumeSet = mutableSetOf<Int>()
|
|
||||||
chapters.forEach {
|
|
||||||
val volNum = getVolumeNumber(it)
|
|
||||||
if (volNum != null) {
|
|
||||||
volumeSet.add(volNum)
|
|
||||||
if (volumeSet.size >= 2) return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hasMultipleSeasons(chapters: List<ChapterItem>): Boolean {
|
|
||||||
val volumeSet = mutableSetOf<Int>()
|
|
||||||
chapters.forEach {
|
|
||||||
val volNum = getSeasonNumber(it)
|
|
||||||
if (volNum != null) {
|
|
||||||
volumeSet.add(volNum)
|
|
||||||
if (volumeSet.size >= 2) return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun hasTensOfChapters(chapters: List<ChapterItem>): Boolean {
|
|
||||||
return chapters.size > 20
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next unread chapter or null if everything is read.
|
* Returns the next unread chapter or null if everything is read.
|
||||||
*/
|
*/
|
||||||
@ -596,10 +519,10 @@ class MangaDetailsPresenter(
|
|||||||
|
|
||||||
fun currentFilters(): String {
|
fun currentFilters(): String {
|
||||||
val filtersId = mutableListOf<Int?>()
|
val filtersId = mutableListOf<Int?>()
|
||||||
filtersId.add(if (onlyRead()) R.string.read else null)
|
filtersId.add(if (manga.readFilter == Manga.SHOW_READ) R.string.read else null)
|
||||||
filtersId.add(if (onlyUnread()) R.string.unread else null)
|
filtersId.add(if (manga.readFilter == Manga.SHOW_UNREAD) R.string.unread else null)
|
||||||
filtersId.add(if (onlyDownloaded()) R.string.downloaded else null)
|
filtersId.add(if (manga.downloadedFilter == Manga.SHOW_DOWNLOADED) R.string.downloaded else null)
|
||||||
filtersId.add(if (onlyBookmarked()) R.string.bookmarked else null)
|
filtersId.add(if (manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED) R.string.bookmarked else null)
|
||||||
return filtersId.filterNotNull().joinToString(", ") { preferences.context.getString(it) }
|
return filtersId.filterNotNull().joinToString(", ") { preferences.context.getString(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.ui.reader
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class filters chapters for the reader based on the user enabled preferences and filters
|
|
||||||
*/
|
|
||||||
class ReaderChapterFilter(
|
|
||||||
private val downloadManager: DownloadManager,
|
|
||||||
private val preferences: PreferencesHelper
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun filterChapter(
|
|
||||||
dbChapters: List<Chapter>,
|
|
||||||
manga: Manga,
|
|
||||||
selectedChapter: Chapter? = null
|
|
||||||
): List<Chapter> {
|
|
||||||
|
|
||||||
// if neither preference is enabled don't even filter
|
|
||||||
if (!preferences.skipRead() && !preferences.skipFiltered()) {
|
|
||||||
return dbChapters
|
|
||||||
}
|
|
||||||
|
|
||||||
var filteredChapters = dbChapters
|
|
||||||
if (preferences.skipRead()) {
|
|
||||||
filteredChapters = filteredChapters.filter { !it.read }
|
|
||||||
}
|
|
||||||
if (preferences.skipFiltered()) {
|
|
||||||
val readEnabled = manga.readFilter == Manga.SHOW_READ
|
|
||||||
val unreadEnabled = manga.readFilter == Manga.SHOW_UNREAD
|
|
||||||
val downloadEnabled = manga.downloadedFilter == Manga.SHOW_DOWNLOADED
|
|
||||||
val bookmarkEnabled = manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED
|
|
||||||
|
|
||||||
// if none of the filters are enabled skip the filtering of them
|
|
||||||
if (readEnabled || unreadEnabled || downloadEnabled || bookmarkEnabled) {
|
|
||||||
|
|
||||||
filteredChapters = filteredChapters.filter {
|
|
||||||
if (readEnabled && it.read.not() ||
|
|
||||||
(unreadEnabled && it.read) ||
|
|
||||||
(bookmarkEnabled && it.bookmark.not()) ||
|
|
||||||
(downloadEnabled && downloadManager.isChapterDownloaded(it, manga).not())
|
|
||||||
) {
|
|
||||||
return@filter false
|
|
||||||
}
|
|
||||||
return@filter true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the selected chapter to the list in case it was filtered out
|
|
||||||
if (selectedChapter?.id != null) {
|
|
||||||
val find = filteredChapters.find { it.id == selectedChapter.id }
|
|
||||||
if (find == null) {
|
|
||||||
val mutableList = filteredChapters.toMutableList()
|
|
||||||
mutableList.add(selectedChapter)
|
|
||||||
filteredChapters = mutableList.toList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filteredChapters
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,6 +27,7 @@ import eu.kanade.tachiyomi.ui.reader.loader.DownloadPageLoader
|
|||||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||||
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
|
||||||
|
import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -53,11 +54,10 @@ class ReaderPresenter(
|
|||||||
private val sourceManager: SourceManager = Injekt.get(),
|
private val sourceManager: SourceManager = Injekt.get(),
|
||||||
private val downloadManager: DownloadManager = Injekt.get(),
|
private val downloadManager: DownloadManager = Injekt.get(),
|
||||||
private val coverCache: CoverCache = Injekt.get(),
|
private val coverCache: CoverCache = Injekt.get(),
|
||||||
private val preferences: PreferencesHelper = Injekt.get()
|
private val preferences: PreferencesHelper = Injekt.get(),
|
||||||
|
private val chapterFilter: ChapterFilter = Injekt.get()
|
||||||
) : BasePresenter<ReaderActivity>() {
|
) : BasePresenter<ReaderActivity>() {
|
||||||
|
|
||||||
private val readerChapterFilter = ReaderChapterFilter(downloadManager, preferences)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The manga loaded in the reader. It can be null when instantiated for a short time.
|
* The manga loaded in the reader. It can be null when instantiated for a short time.
|
||||||
*/
|
*/
|
||||||
@ -101,7 +101,7 @@ class ReaderPresenter(
|
|||||||
?: error("Requested chapter of id $chapterId not found in chapter list")
|
?: error("Requested chapter of id $chapterId not found in chapter list")
|
||||||
|
|
||||||
val chaptersForReader =
|
val chaptersForReader =
|
||||||
readerChapterFilter.filterChapter(dbChapters, manga, selectedChapter)
|
chapterFilter.filterChaptersForReader(dbChapters, manga, selectedChapter)
|
||||||
|
|
||||||
when (manga.sorting) {
|
when (manga.sorting) {
|
||||||
Manga.SORTING_SOURCE -> ChapterLoadBySource().get(chaptersForReader)
|
Manga.SORTING_SOURCE -> ChapterLoadBySource().get(chaptersForReader)
|
||||||
@ -187,7 +187,7 @@ class ReaderPresenter(
|
|||||||
chapterItems = withContext(Dispatchers.IO) {
|
chapterItems = withContext(Dispatchers.IO) {
|
||||||
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
val dbChapters = db.getChapters(manga).executeAsBlocking()
|
||||||
val list =
|
val list =
|
||||||
readerChapterFilter.filterChapter(dbChapters, manga, getCurrentChapter()?.chapter)
|
chapterFilter.filterChaptersForReader(dbChapters, manga, getCurrentChapter()?.chapter)
|
||||||
.sortedBy {
|
.sortedBy {
|
||||||
when (manga.sorting) {
|
when (manga.sorting) {
|
||||||
Manga.SORTING_NUMBER -> it.chapter_number
|
Manga.SORTING_NUMBER -> it.chapter_number
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
package eu.kanade.tachiyomi.util.chapter
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
|
class ChapterFilter(val preferences: PreferencesHelper = Injekt.get(), val downloadManager: DownloadManager = Injekt.get()) {
|
||||||
|
|
||||||
|
// filters chapters based on the manga values
|
||||||
|
fun filterChapters(chapters: List<Chapter>, manga: Manga): List<Chapter> {
|
||||||
|
val readEnabled = manga.readFilter == Manga.SHOW_READ
|
||||||
|
val unreadEnabled = manga.readFilter == Manga.SHOW_UNREAD
|
||||||
|
val downloadEnabled = manga.downloadedFilter == Manga.SHOW_DOWNLOADED
|
||||||
|
val bookmarkEnabled = manga.bookmarkedFilter == Manga.SHOW_BOOKMARKED
|
||||||
|
|
||||||
|
// if none of the filters are enabled skip the filtering of them
|
||||||
|
return if (readEnabled || unreadEnabled || downloadEnabled || bookmarkEnabled) {
|
||||||
|
chapters.filter {
|
||||||
|
if (readEnabled && it.read.not() ||
|
||||||
|
(unreadEnabled && it.read) ||
|
||||||
|
(bookmarkEnabled && it.bookmark.not()) ||
|
||||||
|
(downloadEnabled && downloadManager.isChapterDownloaded(it, manga).not())
|
||||||
|
) {
|
||||||
|
return@filter false
|
||||||
|
}
|
||||||
|
return@filter true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chapters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter chapters for the reader
|
||||||
|
fun filterChaptersForReader(chapters: List<Chapter>, manga: Manga, selectedChapter: Chapter? = null): List<Chapter> {
|
||||||
|
// if neither preference is enabled don't even filter
|
||||||
|
if (!preferences.skipRead() && !preferences.skipFiltered()) {
|
||||||
|
return chapters
|
||||||
|
}
|
||||||
|
|
||||||
|
var filteredChapters = chapters
|
||||||
|
if (preferences.skipRead()) {
|
||||||
|
filteredChapters = filteredChapters.filter { !it.read }
|
||||||
|
}
|
||||||
|
if (preferences.skipFiltered()) {
|
||||||
|
filteredChapters = filterChapters(filteredChapters, manga)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the selected chapter to the list in case it was filtered out
|
||||||
|
if (selectedChapter?.id != null) {
|
||||||
|
val find = filteredChapters.find { it.id == selectedChapter.id }
|
||||||
|
if (find == null) {
|
||||||
|
val mutableList = filteredChapters.toMutableList()
|
||||||
|
mutableList.add(selectedChapter)
|
||||||
|
filteredChapters = mutableList.toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredChapters
|
||||||
|
}
|
||||||
|
}
|
@ -3,10 +3,10 @@ package eu.kanade.tachiyomi.util.chapter
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.graphics.ColorUtils
|
|
||||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||||
import eu.kanade.tachiyomi.util.system.contextCompatColor
|
import eu.kanade.tachiyomi.util.system.contextCompatColor
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
import eu.kanade.tachiyomi.util.system.dpToPxEnd
|
||||||
@ -84,6 +84,55 @@ class ChapterUtil {
|
|||||||
|
|
||||||
private fun bookmarkedColor(context: Context): Int = context.contextCompatColor(R.color.bookmarked_chapter)
|
private fun bookmarkedColor(context: Context): Int = context.contextCompatColor(R.color.bookmarked_chapter)
|
||||||
|
|
||||||
private fun bookmarkedAndReadColor(context: Context): Int = ColorUtils.setAlphaComponent(context.contextCompatColor(R.color.bookmarked_chapter), 150)
|
private val volumeRegex = Regex("""(vol|volume)\.? *([0-9]+)?""", RegexOption.IGNORE_CASE)
|
||||||
|
private val seasonRegex = Regex("""(Season |S)([0-9]+)?""")
|
||||||
|
|
||||||
|
fun getGroupNumber(chapter: Chapter): Int? {
|
||||||
|
val groups = volumeRegex.find(chapter.name)?.groups
|
||||||
|
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
||||||
|
val seasonGroups = seasonRegex.find(chapter.name)?.groups
|
||||||
|
if (seasonGroups != null) return seasonGroups[2]?.value?.toIntOrNull()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVolumeNumber(chapter: Chapter): Int? {
|
||||||
|
val groups = volumeRegex.find(chapter.name)?.groups
|
||||||
|
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSeasonNumber(chapter: Chapter): Int? {
|
||||||
|
val groups = seasonRegex.find(chapter.name)?.groups
|
||||||
|
if (groups != null) return groups[2]?.value?.toIntOrNull()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasMultipleVolumes(chapters: List<Chapter>): Boolean {
|
||||||
|
val volumeSet = mutableSetOf<Int>()
|
||||||
|
chapters.forEach {
|
||||||
|
val volNum = getVolumeNumber(it)
|
||||||
|
if (volNum != null) {
|
||||||
|
volumeSet.add(volNum)
|
||||||
|
if (volumeSet.size >= 2) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasMultipleSeasons(chapters: List<Chapter>): Boolean {
|
||||||
|
val volumeSet = mutableSetOf<Int>()
|
||||||
|
chapters.forEach {
|
||||||
|
val volNum = getSeasonNumber(it)
|
||||||
|
if (volNum != null) {
|
||||||
|
volumeSet.add(volNum)
|
||||||
|
if (volumeSet.size >= 2) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasTensOfChapters(chapters: List<ChapterItem>): Boolean {
|
||||||
|
return chapters.size > 20
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user