Changed Status Filter UI, fixed volumes marking all as read.

This commit is contained in:
Mio.
2025-07-13 22:56:26 +02:00
parent bdfe0aeea5
commit 39ea1cd5fd
2 changed files with 51 additions and 33 deletions

View File

@@ -43,10 +43,15 @@ class SpecialListFilter : Filter.Select<String>(
arrayOf("None", "Want to Read", "Reading Lists"), arrayOf("None", "Want to Read", "Reading Lists"),
) )
// Use Filter.CheckBox directly for status class StatusFilter : Filter.Select<String>(
class StatusFilter(name: String) : Filter.CheckBox(name, false) "Status",
class StatusFilterGroup(filters: List<StatusFilter>) : arrayOf("Any", "Unread", "In Progress", "Read"),
Filter.Group<StatusFilter>("Status", filters) )
class StatusFilterGroup : Filter.Group<StatusFilter>(
"Status",
listOf(StatusFilter()),
)
// Use Filter.Text directly for release year range // Use Filter.Text directly for release year range
class ReleaseYearRange(name: String) : Filter.Text(name, "") class ReleaseYearRange(name: String) : Filter.Text(name, "")

View File

@@ -433,32 +433,36 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
is Filter.Group<*> -> { is Filter.Group<*> -> {
when (filter) { when (filter) {
is StatusFilterGroup -> { is StatusFilterGroup -> {
filter.state.forEach { statusFilter -> val statusFilter = filter.state.firstOrNull() as? StatusFilter
if ((statusFilter as Filter.CheckBox).state) { statusFilter?.state?.let { selectedIndex ->
when (statusFilter.name) { when (selectedIndex) {
"notRead" -> filterV2.addStatement( 1 -> { // Unread (0%)
filterV2.addStatement(
FilterComparison.Equal, FilterComparison.Equal,
FilterField.ReadProgress, FilterField.ReadProgress,
"0", "0",
) )
"inProgress" -> { }
filterV2.addStatement( 2 -> { // In Progress (1-99%)
FilterComparison.GreaterThan, filterV2.addStatement(
FilterField.ReadProgress, FilterComparison.GreaterThanEqual,
"0", FilterField.ReadProgress,
) "1",
filterV2.addStatement( )
FilterComparison.LessThan, filterV2.addStatement(
FilterField.ReadProgress, FilterComparison.LessThanEqual,
"100", FilterField.ReadProgress,
) "99",
} )
"read" -> filterV2.addStatement( }
3 -> { // Read (100%)
filterV2.addStatement(
FilterComparison.Equal, FilterComparison.Equal,
FilterField.ReadProgress, FilterField.ReadProgress,
"100", "100",
) )
} }
// 0 is "Any" - no filter applied
} }
} }
} }
@@ -1422,7 +1426,8 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
} ?: false } ?: false
volumes.forEach { volume -> volumes.forEach { volume ->
if (volume.chapters.size == 1 && volume.name.isNotBlank() && volume.minNumber.toInt() != KavitaConstants.SPECIAL_NUMBER) { // This fixes specials being parsed as volumes
if (volume.chapters.size == 1 && volume.minNumber.toInt() != KavitaConstants.SPECIAL_NUMBER) {
val chapter = volume.chapters.first() val chapter = volume.chapters.first()
val sChapter = helper.chapterFromVolume( val sChapter = helper.chapterFromVolume(
chapter, chapter,
@@ -1453,7 +1458,6 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
if (type == ChapterType.SingleFileVolume) { if (type == ChapterType.SingleFileVolume) {
volumeItems.add(sChapter) volumeItems.add(sChapter)
} else { } else {
sChapter.url = "/Chapter/${chapter.id}"
chapters.add(sChapter) chapters.add(sChapter)
} }
} }
@@ -1461,13 +1465,17 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
} }
return when { return when {
// Case 1: Only chapters
chapters.isNotEmpty() && volumeItems.isEmpty() -> chapters.isNotEmpty() && volumeItems.isEmpty() ->
chapters.sortedByDescending { it.chapter_number } chapters.sortedByDescending { it.chapter_number }
// Case 2: Only volumes - treat as chapters with positive numbers
volumeItems.isNotEmpty() && chapters.isEmpty() -> volumeItems.isNotEmpty() && chapters.isEmpty() ->
volumeItems.sortedByDescending { it.chapter_number } volumeItems.sortedByDescending { it.chapter_number }
// Case 3: Mixed content - chapters first, then volumes
else -> { else -> {
// Convert volume numbers to negative for proper sorting
volumeItems.forEach { it.chapter_number = -it.chapter_number } volumeItems.forEach { it.chapter_number = -it.chapter_number }
( (
chapters.sortedByDescending { it.chapter_number } + chapters.sortedByDescending { it.chapter_number } +
@@ -1569,10 +1577,22 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
val volumeId = chapter.url.substringAfter("/Volume/").substringBefore("?").toIntOrNull() val volumeId = chapter.url.substringAfter("/Volume/").substringBefore("?").toIntOrNull()
?: throw IOException("Invalid volume ID") ?: throw IOException("Invalid volume ID")
// Get all chapters & pages in this volume // Get all pages in this volume
val volumeRequest = GET("$apiUrl/Volume/$volumeId", headersBuilder().build()) val volumeRequest = GET("$apiUrl/Volume/$volumeId", headersBuilder().build())
val volume = client.newCall(volumeRequest).execute().parseAs<VolumeDto>() val volume = client.newCall(volumeRequest).execute().parseAs<VolumeDto>()
val matchingChapter = volume.chapters.firstOrNull() // or match a chapterId if available
?: throw IOException(helper.intl["error_no_chapters_found"])
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
for (i in 0 until matchingChapter.pages) {
pages.add(
Page(
index = i,
imageUrl = "$apiUrl/Reader/image?chapterId=${matchingChapter.id}&page=$i&extractPdf=true&apiKey=$apiKey",
),
)
}
var pageOffset = 0 var pageOffset = 0
volume.chapters.sortedBy { it.number.toFloatOrNull() ?: 0f }.forEach { chapterDto -> volume.chapters.sortedBy { it.number.toFloatOrNull() ?: 0f }.forEach { chapterDto ->
@@ -1616,6 +1636,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
pages.toList() pages.toList()
} }
}.onErrorResumeNext { error -> }.onErrorResumeNext { error ->
// Fallback to using the scanlator field if we can't get chapter details
Log.e(LOG_TAG, "Error fetching chapter details, using fallback", error) Log.e(LOG_TAG, "Error fetching chapter details, using fallback", error)
val fallbackPageCount = chapter.scanlator?.replace(" pages", "")?.toIntOrNull() ?: 1 val fallbackPageCount = chapter.scanlator?.replace(" pages", "")?.toIntOrNull() ?: 1
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
@@ -1686,15 +1707,7 @@ class Kavita(private val suffix: String = "") : ConfigurableSource, UnmeteredSou
filtersLoaded.add(SpecialListFilter()) filtersLoaded.add(SpecialListFilter())
if (toggledFilters.contains("Read Status")) { if (toggledFilters.contains("Read Status")) {
filtersLoaded.add( filtersLoaded.add(StatusFilterGroup())
StatusFilterGroup(
listOf(
"notRead",
"inProgress",
"read",
).map { StatusFilter(it) },
),
)
} }
if (toggledFilters.contains("ReleaseYearRange")) { if (toggledFilters.contains("ReleaseYearRange")) {
filtersLoaded.add( filtersLoaded.add(