ref: add season/episode number in downloads

This commit is contained in:
tapframe 2026-05-06 21:00:51 +05:30
parent eee6d1a2a8
commit b293157fee
2 changed files with 51 additions and 7 deletions

View file

@ -98,3 +98,13 @@ enum class DownloadEnqueueResult {
} }
} }
} }
internal fun List<DownloadItem>.sortedForSeriesDownloads(): List<DownloadItem> =
sortedWith(downloadSeriesEpisodeComparator)
internal val downloadSeriesEpisodeComparator: Comparator<DownloadItem> =
compareBy<DownloadItem> { it.seasonNumber ?: Int.MAX_VALUE }
.thenBy { it.episodeNumber ?: Int.MAX_VALUE }
.thenBy { it.episodeTitle?.trim().orEmpty().lowercase() }
.thenBy { it.title.trim().lowercase() }
.thenBy { it.id }

View file

@ -56,7 +56,7 @@ fun DownloadsScreen(
val completedEpisodes = remember(uiState.items) { val completedEpisodes = remember(uiState.items) {
uiState.completedItems uiState.completedItems
.filter { it.isEpisode } .filter { it.isEpisode }
.sortedByDescending { it.updatedAtEpochMs } .sortedForSeriesDownloads()
} }
val selectedShowTitle = remember(selectedShowId, completedEpisodes) { val selectedShowTitle = remember(selectedShowId, completedEpisodes) {
@ -229,6 +229,7 @@ private fun LazyListScope.downloadsShowContent(
) { ) {
val showEpisodes = episodes val showEpisodes = episodes
.filter { it.parentMetaId == showId } .filter { it.parentMetaId == showId }
.sortedForSeriesDownloads()
val seasons = showEpisodes val seasons = showEpisodes
.groupBy { it.seasonNumber ?: 0 } .groupBy { it.seasonNumber ?: 0 }
@ -268,10 +269,7 @@ private fun LazyListScope.downloadsShowContent(
) )
} }
val sortedEpisodes = entries.sortedWith( val sortedEpisodes = entries.sortedForSeriesDownloads()
compareBy<DownloadItem> { it.episodeNumber ?: Int.MAX_VALUE }
.thenByDescending { it.updatedAtEpochMs },
)
items( items(
items = sortedEpisodes, items = sortedEpisodes,
@ -298,6 +296,12 @@ private fun DownloadRow(
onRetry: () -> Unit, onRetry: () -> Unit,
onDelete: () -> Unit, onDelete: () -> Unit,
) { ) {
val displayTitle = item.displayTitle()
val displaySubtitle = downloadDisplaySubtitle(
item = item,
displayTitle = displayTitle,
)
Surface( Surface(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -322,7 +326,7 @@ private fun DownloadRow(
verticalArrangement = Arrangement.spacedBy(2.dp), verticalArrangement = Arrangement.spacedBy(2.dp),
) { ) {
Text( Text(
text = item.title, text = displayTitle,
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
@ -330,7 +334,7 @@ private fun DownloadRow(
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
Text( Text(
text = item.displaySubtitle, text = displaySubtitle,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant, color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 1, maxLines = 1,
@ -403,6 +407,36 @@ private fun DownloadRow(
} }
} }
private fun DownloadItem.displayTitle(): String =
if (isEpisode) {
episodeTitle?.trim()?.takeIf { it.isNotBlank() } ?: title
} else {
title
}
@Composable
private fun downloadDisplaySubtitle(
item: DownloadItem,
displayTitle: String,
): String {
val seasonNumber = item.seasonNumber
val episodeNumber = item.episodeNumber
if (seasonNumber == null || episodeNumber == null) {
return item.displaySubtitle
}
val episodeCode = stringResource(
Res.string.compose_player_episode_code_full,
seasonNumber,
episodeNumber,
)
return listOf(
episodeCode,
item.episodeTitle?.trim().orEmpty().takeIf { it.isNotBlank() && it != displayTitle },
item.title.trim().takeIf { it.isNotBlank() && it != displayTitle },
).filterNotNull().joinToString("")
}
@Composable @Composable
private fun SectionTitle(title: String) { private fun SectionTitle(title: String) {
Text( Text(