Can now expand history grouped chapters

just like the update sections, the preferences for history its either always collapsed by default, or its separated out
This commit is contained in:
Jays2Kings 2023-03-03 01:10:46 -05:00
parent f1c5f65090
commit addabd70bb
12 changed files with 159 additions and 154 deletions

View file

@ -21,6 +21,9 @@ interface Chapter : SChapter, Serializable {
var source_order: Int var source_order: Int
var dateRead: Long?
var history: History?
val isRecognizedNumber: Boolean val isRecognizedNumber: Boolean
get() = chapter_number >= 0f get() = chapter_number >= 0f

View file

@ -24,6 +24,13 @@ class ChapterImpl : Chapter {
override var date_upload: Long = 0 override var date_upload: Long = 0
override var dateRead: Long? = null
override var history: History? = null
set(value) {
field = value
dateRead = history?.last_read
}
override var chapter_number: Float = 0f override var chapter_number: Float = 0f
override var source_order: Int = 0 override var source_order: Int = 0

View file

@ -35,23 +35,6 @@ interface HistoryQueries : DbProvider {
// .withGetResolver(MangaChapterHistoryGetResolver.INSTANCE) // .withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
// .prepare() // .prepare()
/**
* Returns history of recent manga containing last read chapter in 25s
* @param date recent date range
* @offset offset the db by
*/
fun getRecentMangaLimit(search: String = "", offset: Int, isResuming: Boolean) = db.get()
.listOfObjects(MangaChapterHistory::class.java)
.withQuery(
RawQuery.builder()
.query(getRecentMangasLimitQuery(search.sqLite, offset, isResuming))
// .args(date.time, startDate.time)
.observesTables(HistoryTable.TABLE)
.build(),
)
.withGetResolver(MangaChapterHistoryGetResolver.INSTANCE)
.prepare()
/** /**
* Returns history of recent manga containing last read chapter in 25s * Returns history of recent manga containing last read chapter in 25s
* @param date recent date range * @param date recent date range
@ -62,7 +45,6 @@ interface HistoryQueries : DbProvider {
.withQuery( .withQuery(
RawQuery.builder() RawQuery.builder()
.query(getRecentHistoryUngrouped(search.sqLite, offset, isResuming)) .query(getRecentHistoryUngrouped(search.sqLite, offset, isResuming))
// .args(date.time, startDate.time)
.observesTables(HistoryTable.TABLE) .observesTables(HistoryTable.TABLE)
.build(), .build(),
) )

View file

@ -61,18 +61,6 @@ fun getRecentsQuery(search: String, offset: Int, isResuming: Boolean) =
${limitAndOffset(true, isResuming, offset)} ${limitAndOffset(true, isResuming, offset)}
""" """
/**
* Query to get the recently added manga
*/
fun getRecentAdditionsQuery(search: String, endless: Boolean, offset: Int, isResuming: Boolean) =
"""
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, * FROM ${Manga.TABLE}
WHERE ${Manga.COL_FAVORITE} = 1
AND lower(${Manga.COL_TITLE}) LIKE '%$search%'
ORDER BY ${Manga.COL_DATE_ADDED} DESC
${limitAndOffset(endless, isResuming, offset)}
"""
fun limitAndOffset(endless: Boolean, isResuming: Boolean, offset: Int): String { fun limitAndOffset(endless: Boolean, isResuming: Boolean, offset: Int): String {
return when { return when {
isResuming && endless && offset > 0 -> "LIMIT $offset" isResuming && endless && offset > 0 -> "LIMIT $offset"
@ -81,37 +69,6 @@ fun limitAndOffset(endless: Boolean, isResuming: Boolean, offset: Int): String {
} }
} }
/**
* Query to get the recently read chapters of manga from the library up to a date.
* The max_last_read table contains the most recent chapters grouped by manga
* The select statement returns all information of chapters that have the same id as the chapter in max_last_read
* and are read after the given time period
*/
fun getRecentMangasLimitQuery(
search: String = "",
offset: Int = 0,
isResuming: Boolean,
) =
"""
SELECT ${Manga.TABLE}.${Manga.COL_URL} as mangaUrl, ${Manga.TABLE}.*, ${Chapter.TABLE}.*, ${History.TABLE}.*
FROM ${Manga.TABLE}
JOIN ${Chapter.TABLE}
ON ${Manga.TABLE}.${Manga.COL_ID} = ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}
JOIN ${History.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
JOIN (
SELECT ${Chapter.TABLE}.${Chapter.COL_MANGA_ID},${Chapter.TABLE}.${Chapter.COL_ID} as ${History.COL_CHAPTER_ID}, MAX(${History.TABLE}.${History.COL_LAST_READ}) as ${History.COL_LAST_READ}
FROM ${Chapter.TABLE} JOIN ${History.TABLE}
ON ${Chapter.TABLE}.${Chapter.COL_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
GROUP BY ${Chapter.TABLE}.${Chapter.COL_MANGA_ID}) AS max_last_read
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
AND max_last_read.${History.COL_LAST_READ} > 0
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
${limitAndOffset(true, isResuming, offset)}
"""
/** /**
* Query to get the recently read chapters of manga from the library up to a date. * Query to get the recently read chapters of manga from the library up to a date.
* The max_last_read table contains the most recent chapters grouped by manga * The max_last_read table contains the most recent chapters grouped by manga

View file

@ -88,6 +88,7 @@ class RecentMangaAdapter(val delegate: RecentsInterface) :
fun isSearching(): Boolean fun isSearching(): Boolean
fun scope(): CoroutineScope fun scope(): CoroutineScope
fun getViewType(): Int fun getViewType(): Int
fun onItemLongClick(position: Int, chapter: Chapter): Boolean
} }
override fun onItemSwiped(position: Int, direction: Int) { override fun onItemSwiped(position: Int, direction: Int) {

View file

@ -39,9 +39,11 @@ class RecentMangaHolder(
private val binding = RecentMangaItemBinding.bind(view) private val binding = RecentMangaItemBinding.bind(view)
var chapterId: Long? = null var chapterId: Long? = null
private val isUpdates
get() = adapter.viewType == RecentsPresenter.VIEW_TYPE_ONLY_UPDATES
private val isSmallUpdates private val isSmallUpdates
get() = adapter.viewType == RecentsPresenter.VIEW_TYPE_ONLY_UPDATES && get() = isUpdates && !adapter.showUpdatedTime
!adapter.showUpdatedTime
init { init {
binding.cardLayout.setOnClickListener { adapter.delegate.onCoverClick(flexibleAdapterPosition) } binding.cardLayout.setOnClickListener { adapter.delegate.onCoverClick(flexibleAdapterPosition) }
@ -62,7 +64,7 @@ class RecentMangaHolder(
RecentSubChapterItemBinding.bind(view).updateDivider() RecentSubChapterItemBinding.bind(view).updateDivider()
} }
} }
if (binding.moreChaptersLayout.children.any { view -> if (isUpdates && binding.moreChaptersLayout.children.any { view ->
!RecentSubChapterItemBinding.bind(view).subtitle.text.isNullOrBlank() !RecentSubChapterItemBinding.bind(view).subtitle.text.isNullOrBlank()
} }
) { ) {
@ -230,7 +232,7 @@ class RecentMangaHolder(
RecentSubChapterItemBinding.bind(binding.moreChaptersLayout.getChildAt(index)) RecentSubChapterItemBinding.bind(binding.moreChaptersLayout.getChildAt(index))
.configureView(chapter, item) .configureView(chapter, item)
} }
if (binding.moreChaptersLayout.children.any { view -> if (isUpdates && binding.moreChaptersLayout.children.any { view ->
!RecentSubChapterItemBinding.bind(view).subtitle.text.isNullOrBlank() !RecentSubChapterItemBinding.bind(view).subtitle.text.isNullOrBlank()
} }
) { ) {
@ -247,7 +249,7 @@ class RecentMangaHolder(
true, true,
) )
binding.configureView(chapter, item) binding.configureView(chapter, item)
if (chapter.isRecognizedNumber && if (isUpdates && chapter.isRecognizedNumber &&
chapter.chapter_number == item.chapter.chapter_number && chapter.chapter_number == item.chapter.chapter_number &&
!chapter.scanlator.isNullOrBlank() !chapter.scanlator.isNullOrBlank()
) { ) {
@ -309,13 +311,20 @@ class RecentMangaHolder(
val showDLs = adapter.showDownloads val showDLs = adapter.showDownloads
title.text = chapter.preferredChapterName(context, item.mch.manga, adapter.preferences) title.text = chapter.preferredChapterName(context, item.mch.manga, adapter.preferences)
title.setTextColor(ChapterUtil.readColor(context, chapter)) title.setTextColor(ChapterUtil.readColor(context, chapter))
chapter.dateRead?.let { dateRead ->
subtitle.text = context.timeSpanFromNow(R.string.read_, dateRead)
subtitle.isVisible = true
}
root.setOnClickListener { root.setOnClickListener {
adapter.delegate.onSubChapterClicked( adapter.delegate.onSubChapterClicked(
flexibleAdapterPosition, bindingAdapterPosition,
chapter, chapter,
it, it,
) )
} }
root.setOnLongClickListener {
adapter.delegate.onItemLongClick(bindingAdapterPosition, chapter)
}
listOf(root, downloadButton.root).forEach { listOf(root, downloadButton.root).forEach {
it.setOnTouchListener { _, event -> it.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) { if (event.action == MotionEvent.ACTION_DOWN) {

View file

@ -652,7 +652,7 @@ class RecentsController(bundle: Bundle? = null) :
override fun areExtraChaptersExpanded(position: Int): Boolean { override fun areExtraChaptersExpanded(position: Int): Boolean {
val item = (adapter.getItem(position) as? RecentMangaItem) ?: return false val item = (adapter.getItem(position) as? RecentMangaItem) ?: return false
val date = presenter.dateFormat.format(item.chapter.date_fetch) val date = presenter.dateFormat.format(item.chapter.dateRead ?: item.chapter.date_fetch)
val invertDefault = !adapter.collapseGroupedUpdates val invertDefault = !adapter.collapseGroupedUpdates
return presenter.expandedSectionsMap["${item.mch.manga} - $date"]?.xor(invertDefault) return presenter.expandedSectionsMap["${item.mch.manga} - $date"]?.xor(invertDefault)
?: invertDefault ?: invertDefault
@ -660,7 +660,7 @@ class RecentsController(bundle: Bundle? = null) :
override fun updateExpandedExtraChapters(position: Int, expanded: Boolean) { override fun updateExpandedExtraChapters(position: Int, expanded: Boolean) {
val item = (adapter.getItem(position) as? RecentMangaItem) ?: return val item = (adapter.getItem(position) as? RecentMangaItem) ?: return
val date = presenter.dateFormat.format(item.chapter.date_fetch) val date = presenter.dateFormat.format(item.chapter.dateRead ?: item.chapter.date_fetch)
val invertDefault = !adapter.collapseGroupedUpdates val invertDefault = !adapter.collapseGroupedUpdates
presenter.expandedSectionsMap["${item.mch.manga} - $date"] = expanded.xor(invertDefault) presenter.expandedSectionsMap["${item.mch.manga} - $date"] = expanded.xor(invertDefault)
} }
@ -727,6 +727,16 @@ class RecentsController(bundle: Bundle? = null) :
} }
} }
override fun onItemLongClick(position: Int, chapter: Chapter): Boolean {
val history = chapter.history ?: return false
val item = adapter.getItem(position) as? RecentMangaItem ?: return false
val manga = item.mch.manga
if (history.id != null) {
RemoveHistoryDialog(this, manga, history, chapter).showDialog(router)
}
return history.id != null
}
override fun removeHistory(manga: Manga, history: History, all: Boolean) { override fun removeHistory(manga: Manga, history: History, all: Boolean) {
if (all) { if (all) {
// Reset last read of chapter to 0L // Reset last read of chapter to 0L

View file

@ -6,7 +6,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.History import eu.kanade.tachiyomi.data.database.models.History
import eu.kanade.tachiyomi.data.database.models.HistoryImpl import eu.kanade.tachiyomi.data.database.models.HistoryImpl
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaChapter
import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadService
@ -19,6 +18,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter import eu.kanade.tachiyomi.ui.base.presenter.BaseCoroutinePresenter
import eu.kanade.tachiyomi.util.chapter.ChapterFilter import eu.kanade.tachiyomi.util.chapter.ChapterFilter
import eu.kanade.tachiyomi.util.chapter.ChapterFilter.Companion.filterChaptersByScanlators
import eu.kanade.tachiyomi.util.chapter.ChapterSort import eu.kanade.tachiyomi.util.chapter.ChapterSort
import eu.kanade.tachiyomi.util.system.executeOnIO import eu.kanade.tachiyomi.util.system.executeOnIO
import eu.kanade.tachiyomi.util.system.launchIO import eu.kanade.tachiyomi.util.system.launchIO
@ -60,12 +60,9 @@ class RecentsPresenter(
} }
private val newAdditionsHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEWLY_ADDED) private val newAdditionsHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEWLY_ADDED)
private val newChaptersHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEW_CHAPTERS) private val newChaptersHeader = RecentMangaHeaderItem(RecentMangaHeaderItem.NEW_CHAPTERS)
private val continueReadingHeader = RecentMangaHeaderItem( private val continueReadingHeader =
RecentMangaHeaderItem RecentMangaHeaderItem(RecentMangaHeaderItem.CONTINUE_READING)
.CONTINUE_READING,
)
var finished = false var finished = false
var heldItems: HashMap<Int, List<RecentMangaItem>> = hashMapOf()
private var shouldMoveToTop = false private var shouldMoveToTop = false
var viewType: Int = preferences.recentsViewType().get() var viewType: Int = preferences.recentsViewType().get()
private set private set
@ -173,19 +170,40 @@ class RecentsPresenter(
).executeOnIO() ).executeOnIO()
} }
viewType == VIEW_TYPE_ONLY_HISTORY -> { viewType == VIEW_TYPE_ONLY_HISTORY -> {
val items = db.getHistoryUngrouped(
query,
if (isCustom) ENDLESS_LIMIT else pageOffset,
!updatePageCount && !isOnFirstPage,
)
if (groupChaptersHistory) { if (groupChaptersHistory) {
db.getRecentMangaLimit( items.executeOnIO().groupBy {
query, val date = it.history.last_read
if (isCustom) ENDLESS_LIMIT else pageOffset, it.manga.id to if (date <= 0L) "-1" else dateFormat.format(Date(date))
!updatePageCount && !isOnFirstPage, }
) .mapNotNull { (key, mchs) ->
val manga = mchs.first().manga
val chapters = mchs.map { mch ->
mch.chapter.also { it.history = mch.history }
}.filterChaptersByScanlators(manga)
if (chapters.isEmpty()) return@mapNotNull null
val existingItem = recentItems.find {
val date = Date(it.mch.history.last_read)
key == it.manga_id to dateFormat.format(date)
}?.takeIf { updatePageCount }
val sort = Comparator<Chapter> { c1, c2 ->
c2.dateRead!!.compareTo(c1.dateRead!!)
}
val (sortedChapters, firstChapter, subCount) =
setupExtraChapters(existingItem, chapters, sort)
?: return@mapNotNull null
extraCount += subCount
mchs.find { firstChapter.id == it.chapter.id }?.also {
it.extraChapters = sortedChapters
}
}
} else { } else {
db.getHistoryUngrouped( items.executeOnIO()
query, }
if (isCustom) ENDLESS_LIMIT else pageOffset,
!updatePageCount && !isOnFirstPage,
)
}.executeOnIO()
} }
viewType == VIEW_TYPE_ONLY_UPDATES -> { viewType == VIEW_TYPE_ONLY_UPDATES -> {
db.getRecentChapters( db.getRecentChapters(
@ -196,49 +214,21 @@ class RecentsPresenter(
val date = it.chapter.date_fetch val date = it.chapter.date_fetch
it.manga.id to if (date <= 0L) "-1" else dateFormat.format(Date(date)) it.manga.id to if (date <= 0L) "-1" else dateFormat.format(Date(date))
} }
.mapNotNull { entry -> .mapNotNull { (key, mcs) ->
val manga = entry.value.first().manga val manga = mcs.first().manga
val chapters = chapterFilter.filterChaptersByScanlators( val chapters = mcs.map { it.chapter }.filterChaptersByScanlators(manga)
entry.value.map(MangaChapter::chapter), if (chapters.isEmpty()) return@mapNotNull null
manga,
)
if (chapters.isEmpty()) { return@mapNotNull null }
val firstChapter: Chapter
var sortedChapters: MutableList<Chapter>
val existingItem = recentItems.find { val existingItem = recentItems.find {
val date = Date(it.chapter.date_fetch) val date = Date(it.chapter.date_fetch)
entry.key == it.manga_id to dateFormat.format(date) key == it.manga_id to dateFormat.format(date)
}?.takeIf { updatePageCount } }?.takeIf { updatePageCount }
if (existingItem != null) {
extraCount += chapters.size
val newChapters = existingItem.mch.extraChapters + chapters
val sort: Comparator<Chapter> = val sort: Comparator<Chapter> =
ChapterSort(manga, chapterFilter, preferences) ChapterSort(manga, chapterFilter, preferences)
.sortComparator(true) .sortComparator(true)
sortedChapters = newChapters.sortedWith(sort).toMutableList() val (sortedChapters, firstChapter, subCount) =
sortedChapters = ( setupExtraChapters(existingItem, chapters, sort)
sortedChapters.filter { !it.read } + ?: return@mapNotNull null
sortedChapters.filter { it.read }.reversed() extraCount += subCount
).toMutableList()
existingItem.mch.extraChapters = sortedChapters
return@mapNotNull null
}
if (chapters.size == 1) {
firstChapter = chapters.first()
sortedChapters = mutableListOf()
} else {
val sort: Comparator<Chapter> =
ChapterSort(manga, chapterFilter, preferences)
.sortComparator(true)
sortedChapters = chapters.sortedWith(sort).toMutableList()
firstChapter =
sortedChapters.firstOrNull { !it.read } ?: sortedChapters.last()
sortedChapters.remove(firstChapter)
sortedChapters = (
sortedChapters.filter { !it.read } +
sortedChapters.filter { it.read }.reversed()
).toMutableList()
}
MangaChapterHistory( MangaChapterHistory(
manga, manga,
firstChapter, firstChapter,
@ -281,8 +271,15 @@ class RecentsPresenter(
it.chapter it.chapter
} }
(it.chapter.read && viewType != VIEW_TYPE_ONLY_UPDATES) || it.chapter.id == null -> { (it.chapter.read && viewType != VIEW_TYPE_ONLY_UPDATES) || it.chapter.id == null -> {
getNextChapter(it.manga) val nextChapter = getNextChapter(it.manga)
?: if (showRead && it.chapter.id != null) it.chapter else null ?: if (showRead && it.chapter.id != null) it.chapter else null
if (viewType == VIEW_TYPE_ONLY_HISTORY && nextChapter?.id != null &&
nextChapter.id != it.chapter.id
) {
nextChapter.dateRead = it.chapter.dateRead
it.extraChapters = listOf(it.chapter) + it.extraChapters
}
nextChapter
} }
it.history.id == null && viewType != VIEW_TYPE_ONLY_UPDATES -> { it.history.id == null && viewType != VIEW_TYPE_ONLY_UPDATES -> {
getFirstUpdatedChapter(it.manga, it.chapter) getFirstUpdatedChapter(it.manga, it.chapter)
@ -369,8 +366,6 @@ class RecentsPresenter(
} else { } else {
recentItems + newItems recentItems + newItems
} }
} else {
heldItems[customViewType] = newItems
} }
val newCount = itemCount + newItems.size + newItems.sumOf { it.mch.extraChapters.size } + extraCount val newCount = itemCount + newItems.size + newItems.sumOf { it.mch.extraChapters.size } + extraCount
val hasNewItems = newItems.isNotEmpty() val hasNewItems = newItems.isNotEmpty()
@ -393,6 +388,45 @@ class RecentsPresenter(
} }
} }
private fun setupExtraChapters(
existingItem: RecentMangaItem?,
chapters: List<Chapter>,
sort: Comparator<Chapter>,
): Triple<MutableList<Chapter>, Chapter, Int>? {
var extraCount = 0
val firstChapter: Chapter
var sortedChapters: MutableList<Chapter>
val reverseRead = viewType != VIEW_TYPE_ONLY_HISTORY
if (existingItem != null) {
extraCount += chapters.size
val newChapters = existingItem.mch.extraChapters + chapters
sortedChapters = newChapters.sortedWith(sort).toMutableList()
sortedChapters = (
sortedChapters.filter { !it.read } +
sortedChapters.filter { it.read }
.run { if (reverseRead) reversed() else this }
).toMutableList()
existingItem.mch.extraChapters = sortedChapters
return null
}
if (chapters.size == 1) {
firstChapter = chapters.first()
sortedChapters = mutableListOf()
} else {
sortedChapters = chapters.sortedWith(sort).toMutableList()
firstChapter = sortedChapters.firstOrNull { !it.read }
?: sortedChapters.run { if (reverseRead) last() else first() }
sortedChapters.last()
sortedChapters.remove(firstChapter)
sortedChapters = (
sortedChapters.filter { !it.read } +
sortedChapters.filter { it.read }
.run { if (reverseRead) reversed() else this }
).toMutableList()
}
return Triple(sortedChapters, firstChapter, extraCount)
}
private fun getNextChapter(manga: Manga): Chapter? { private fun getNextChapter(manga: Manga): Chapter? {
val chapters = db.getChapters(manga).executeAsBlocking() val chapters = db.getChapters(manga).executeAsBlocking()
return ChapterSort(manga, chapterFilter, preferences).getNextUnreadChapter(chapters, false) return ChapterSort(manga, chapterFilter, preferences).getNextUnreadChapter(chapters, false)
@ -564,7 +598,6 @@ class RecentsPresenter(
/** /**
* Mark the selected chapter list as read/unread. * Mark the selected chapter list as read/unread.
* @param selectedChapters the list of selected chapters.
* @param read whether to mark chapters as read or unread. * @param read whether to mark chapters as read or unread.
*/ */
fun markChapterRead( fun markChapterRead(

View file

@ -19,7 +19,7 @@ class ChapterFilter(val preferences: PreferencesHelper = Injekt.get(), val downl
val notBookmarkEnabled = manga.bookmarkedFilter(preferences) == Manga.CHAPTER_SHOW_NOT_BOOKMARKED val notBookmarkEnabled = manga.bookmarkedFilter(preferences) == Manga.CHAPTER_SHOW_NOT_BOOKMARKED
// if none of the filters are enabled skip the filtering of them // if none of the filters are enabled skip the filtering of them
val filteredChapters = filterChaptersByScanlators(chapters, manga) val filteredChapters = chapters.filterChaptersByScanlators(manga)
return if (readEnabled || unreadEnabled || downloadEnabled || notDownloadEnabled || bookmarkEnabled || notBookmarkEnabled) { return if (readEnabled || unreadEnabled || downloadEnabled || notDownloadEnabled || bookmarkEnabled || notBookmarkEnabled) {
filteredChapters.filter { filteredChapters.filter {
if (readEnabled && it.read.not() || if (readEnabled && it.read.not() ||
@ -40,7 +40,7 @@ class ChapterFilter(val preferences: PreferencesHelper = Injekt.get(), val downl
/** filter chapters for the reader */ /** filter chapters for the reader */
fun <T : Chapter> filterChaptersForReader(chapters: List<T>, manga: Manga, selectedChapter: T? = null): List<T> { fun <T : Chapter> filterChaptersForReader(chapters: List<T>, manga: Manga, selectedChapter: T? = null): List<T> {
var filteredChapters = filterChaptersByScanlators(chapters, manga) var filteredChapters = chapters.filterChaptersByScanlators(manga)
// if filter prefs aren't enabled don't even filter // if filter prefs aren't enabled don't even filter
if (!preferences.skipRead() && !preferences.skipFiltered() && !preferences.skipDupe().get()) { if (!preferences.skipRead() && !preferences.skipFiltered() && !preferences.skipDupe().get()) {
return filteredChapters return filteredChapters
@ -82,11 +82,13 @@ class ChapterFilter(val preferences: PreferencesHelper = Injekt.get(), val downl
return filteredChapters return filteredChapters
} }
companion object {
/** filters chapters for scanlators */ /** filters chapters for scanlators */
fun <T : Chapter> filterChaptersByScanlators(chapters: List<T>, manga: Manga): List<T> { fun <T : Chapter> List<T>.filterChaptersByScanlators(manga: Manga): List<T> {
return manga.filtered_scanlators?.let { filteredScanlatorString -> return manga.filtered_scanlators?.let { filteredScanlatorString ->
val filteredScanlators = ChapterUtil.getScanlators(filteredScanlatorString) val filteredScanlators = ChapterUtil.getScanlators(filteredScanlatorString)
chapters.filter { ChapterUtil.getScanlators(it.scanlator).none { group -> filteredScanlators.contains(group) } } filter { ChapterUtil.getScanlators(it.scanlator).none { group -> filteredScanlators.contains(group) } }
} ?: chapters } ?: this
}
} }
} }

View file

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.util.chapter
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.chapter.ChapterFilter.Companion.filterChaptersByScanlators
import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -31,7 +32,7 @@ class ChapterSort(val manga: Manga, val chapterFilter: ChapterFilter = Injekt.ge
fun <T : Chapter> getNextUnreadChapter(rawChapters: List<T>, andFiltered: Boolean = true): T? { fun <T : Chapter> getNextUnreadChapter(rawChapters: List<T>, andFiltered: Boolean = true): T? {
val chapters = when { val chapters = when {
andFiltered -> chapterFilter.filterChapters(rawChapters, manga) andFiltered -> chapterFilter.filterChapters(rawChapters, manga)
else -> chapterFilter.filterChaptersByScanlators(rawChapters, manga) else -> rawChapters.filterChaptersByScanlators(manga)
} }
return chapters.sortedWith(sortComparator(true)).find { !it.read } return chapters.sortedWith(sortComparator(true)).find { !it.read }

View file

@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.chapter.ChapterFilter.Companion.filterChaptersByScanlators
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.util.Date
@ -32,7 +33,6 @@ fun syncChaptersWithSource(
} }
val downloadManager: DownloadManager = Injekt.get() val downloadManager: DownloadManager = Injekt.get()
val chapterFilter: ChapterFilter = Injekt.get()
// Chapters from db. // Chapters from db.
val dbChapters = db.getChapters(manga).executeAsBlocking() val dbChapters = db.getChapters(manga).executeAsBlocking()
@ -169,9 +169,10 @@ fun syncChaptersWithSource(
} }
db.updateLastUpdated(manga).executeAsBlocking() db.updateLastUpdated(manga).executeAsBlocking()
} }
val reAddedSet = readded.toSet()
return Pair( return Pair(
chapterFilter.filterChaptersByScanlators(toAdd.subtract(readded).toList(), manga), toAdd.subtract(reAddedSet).toList().filterChaptersByScanlators(manga),
toDelete - readded, toDelete - reAddedSet,
) )
} }

View file

@ -178,18 +178,6 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitle"> app:layout_constraintTop_toBottomOf="@id/subtitle">
<ImageButton
android:id="@+id/remove_history"
android:layout_width="45dp"
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/reset_chapter_history"
android:padding="8dp"
android:tooltipText="@string/reset_chapter_history"
app:layout_constraintHorizontal_chainStyle="spread"
app:srcCompat="@drawable/ic_eye_remove_outline_24dp"
app:tint="@color/holo_red" />
<ImageButton <ImageButton
android:id="@+id/show_more_chapters" android:id="@+id/show_more_chapters"
android:layout_width="45dp" android:layout_width="45dp"
@ -205,6 +193,17 @@
app:tint="?attr/colorSecondary" app:tint="?attr/colorSecondary"
app:srcCompat="@drawable/ic_expand_more_24dp" /> app:srcCompat="@drawable/ic_expand_more_24dp" />
<ImageButton
android:id="@+id/remove_history"
android:layout_width="45dp"
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/reset_chapter_history"
android:padding="8dp"
android:tooltipText="@string/reset_chapter_history"
app:layout_constraintHorizontal_chainStyle="spread"
app:srcCompat="@drawable/ic_eye_remove_outline_24dp"
app:tint="@color/holo_red" />
<include <include
android:id="@+id/download_button" android:id="@+id/download_button"
layout="@layout/download_button" layout="@layout/download_button"