This commit is contained in:
Sobhan 2026-08-01 04:02:14 +03:00 committed by GitHub
commit 023ace7ef9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 7 deletions

View file

@ -20,6 +20,10 @@ enum class LibrarySortOption {
ADDED_ASC,
TITLE_ASC,
TITLE_DESC,
RATING_DESC,
RATING_ASC,
RELEASE_DATE_DESC,
RELEASE_DATE_ASC,
}
data class LibraryDisplaySettingsUiState(
@ -131,6 +135,26 @@ internal fun sortLibraryItems(
compareByDescending<LibraryItem> { libraryTitleSortKey(it) }
.thenBy { it.id },
)
LibrarySortOption.RATING_DESC -> items.sortedWith(
compareByDescending<LibraryItem> { it.imdbRating?.toFloatOrNull() ?: 0f }
.thenBy { libraryTitleTieBreakKey(it) }
.thenBy { it.id },
)
LibrarySortOption.RATING_ASC -> items.sortedWith(
compareBy<LibraryItem> { it.imdbRating?.toFloatOrNull() ?: Float.MAX_VALUE }
.thenBy { libraryTitleTieBreakKey(it) }
.thenBy { it.id },
)
LibrarySortOption.RELEASE_DATE_DESC -> items.sortedWith(
compareByDescending<LibraryItem> { releaseDateSortKey(it) }
.thenBy { libraryTitleTieBreakKey(it) }
.thenBy { it.id },
)
LibrarySortOption.RELEASE_DATE_ASC -> items.sortedWith(
compareBy<LibraryItem> { releaseDateSortKey(it) }
.thenBy { libraryTitleTieBreakKey(it) }
.thenBy { it.id },
)
}
internal fun sortLibrarySections(
@ -227,18 +251,22 @@ private val LibraryDisplaySettingsJson = Json {
encodeDefaults = true
}
private val LeadingLibraryTitleArticle = Regex("^(the|an|a)\\s+", RegexOption.IGNORE_CASE)
private fun libraryTitleSortKey(item: LibraryItem): String =
libraryTitleTieBreakKey(item)
.trim()
.replace(LeadingLibraryTitleArticle, "")
private fun libraryTitleTieBreakKey(item: LibraryItem): String =
item.name
.ifBlank { item.id }
.lowercase()
private val IsoDateRegex = Regex("\\b\\d{4}(-\\d{2})?(-\\d{2})?\\b")
private fun releaseDateSortKey(item: LibraryItem): String {
val info = item.releaseInfo.orEmpty().trim()
if (info.isBlank()) return ""
return IsoDateRegex.find(info)?.value ?: info.lowercase()
}
private fun libraryDisplayItemKey(item: LibraryItem): String =
"${item.type.normalizedLibraryType()}:${item.id.trim()}"

View file

@ -163,6 +163,10 @@ private fun librarySortOptionLabel(option: LibrarySortOption): String =
LibrarySortOption.ADDED_ASC -> stringResource(Res.string.library_sort_added_asc)
LibrarySortOption.TITLE_ASC -> stringResource(Res.string.library_sort_title_asc)
LibrarySortOption.TITLE_DESC -> stringResource(Res.string.library_sort_title_desc)
LibrarySortOption.RATING_DESC -> "Rating (Highest)"
LibrarySortOption.RATING_ASC -> "Rating (Lowest)"
LibrarySortOption.RELEASE_DATE_DESC -> "Release Date (Newest)"
LibrarySortOption.RELEASE_DATE_ASC -> "Release Date (Oldest)"
}
private fun List<LibraryVerticalEntry>.findEntry(preview: MetaPreview): LibraryVerticalEntry? =

View file

@ -51,7 +51,7 @@ class LibraryDisplaySettingsTest {
}
@Test
fun `title sorting ignores leading English articles`() {
fun `title sorting preserves leading articles for literal alphabetical order`() {
val input = listOf(
item("batman", name = "The Batman"),
item("arrival", name = "Arrival"),
@ -59,11 +59,11 @@ class LibraryDisplaySettingsTest {
)
assertEquals(
listOf("arrival", "batman", "quiet"),
listOf("quiet", "arrival", "batman"),
sortLibraryItems(input, LibrarySortOption.TITLE_ASC, LibrarySourceMode.LOCAL).map { it.id },
)
assertEquals(
listOf("quiet", "batman", "arrival"),
listOf("batman", "arrival", "quiet"),
sortLibraryItems(input, LibrarySortOption.TITLE_DESC, LibrarySourceMode.LOCAL).map { it.id },
)
}