mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 07:29:14 +01:00
downloads: base album/artist progress on completed tracks
The aggregate summed bytes over only the currently active songs, so it reset each time a track finished and the next one started. Count completed tracks (plus the fraction of each running track) over the node's full track count instead, so it climbs one track at a time.
This commit is contained in:
@@ -146,13 +146,14 @@ fun DownloadsScreen(
|
|||||||
tree.artists.forEach { artist ->
|
tree.artists.forEach { artist ->
|
||||||
val artistKey = "artist:${artist.id}:${artist.name}"
|
val artistKey = "artist:${artist.id}:${artist.name}"
|
||||||
item(key = artistKey) {
|
item(key = artistKey) {
|
||||||
val active = activeDownloads(artist.albums.flatMap { it.songs })
|
val songs = artist.albums.flatMap { it.songs }
|
||||||
|
val active = activeDownloads(songs)
|
||||||
NodeRow(
|
NodeRow(
|
||||||
name = artist.name,
|
name = artist.name,
|
||||||
subtitle = "${artist.albums.size} albums · ${size(artist.bytes)}",
|
subtitle = "${artist.albums.size} albums · ${size(artist.bytes)}",
|
||||||
expanded = artistKey in expanded,
|
expanded = artistKey in expanded,
|
||||||
indent = 0,
|
indent = 0,
|
||||||
progress = active.progress(),
|
progress = nodeProgress(songs),
|
||||||
onToggle = { expanded = expanded.toggle(artistKey) },
|
onToggle = { expanded = expanded.toggle(artistKey) },
|
||||||
onDelete = {
|
onDelete = {
|
||||||
onDelete(
|
onDelete(
|
||||||
@@ -176,7 +177,7 @@ fun DownloadsScreen(
|
|||||||
subtitle = "${album.songs.size} songs · ${size(album.bytes)}",
|
subtitle = "${album.songs.size} songs · ${size(album.bytes)}",
|
||||||
expanded = albumKey in expanded,
|
expanded = albumKey in expanded,
|
||||||
indent = 1,
|
indent = 1,
|
||||||
progress = active.progress(),
|
progress = nodeProgress(album.songs),
|
||||||
onToggle = { expanded = expanded.toggle(albumKey) },
|
onToggle = { expanded = expanded.toggle(albumKey) },
|
||||||
onDelete = {
|
onDelete = {
|
||||||
onDelete(
|
onDelete(
|
||||||
@@ -277,10 +278,12 @@ private fun NodeRow(
|
|||||||
private fun activeDownloads(songs: List<DownloadedSong>): List<DownloadedSong> =
|
private fun activeDownloads(songs: List<DownloadedSong>): List<DownloadedSong> =
|
||||||
songs.filter { it.status == DownloadStatus.Queued || it.status == DownloadStatus.Running }
|
songs.filter { it.status == DownloadStatus.Queued || it.status == DownloadStatus.Running }
|
||||||
|
|
||||||
private fun List<DownloadedSong>.progress(): Float? {
|
internal fun nodeProgress(songs: List<DownloadedSong>): Float? {
|
||||||
if (isEmpty()) return null
|
val active = activeDownloads(songs)
|
||||||
val total = sumOf { it.total }
|
if (active.isEmpty() || songs.isEmpty()) return null
|
||||||
return if (total > 0) (sumOf { it.bytes }.toFloat() / total).coerceIn(0f, 1f) else 0f
|
val completed = songs.count { it.status == DownloadStatus.Completed }
|
||||||
|
val partial = active.sumOf { (it.progress ?: 0f).toDouble() }
|
||||||
|
return ((completed + partial) / songs.size).toFloat().coerceIn(0f, 1f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.subtracks.ui.downloads
|
|||||||
import com.subtracks.data.model.DownloadStatus
|
import com.subtracks.data.model.DownloadStatus
|
||||||
import com.subtracks.data.model.DownloadedSong
|
import com.subtracks.data.model.DownloadedSong
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class DownloadTreeTest {
|
class DownloadTreeTest {
|
||||||
@@ -44,6 +45,19 @@ class DownloadTreeTest {
|
|||||||
assertEquals("Unknown album", artist.albums.single().name)
|
assertEquals("Unknown album", artist.albums.single().name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun nodeProgressCountsCompletedTracksRatherThanBytes() {
|
||||||
|
val songs =
|
||||||
|
listOf(
|
||||||
|
song("s1", "One", "ar1", "Artist", "al1", "Album", size = 100),
|
||||||
|
song("s2", "Two", "ar1", "Artist", "al1", "Album", size = 50)
|
||||||
|
.copy(status = DownloadStatus.Running, bytes = 50, total = 100),
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(0.75f, nodeProgress(songs)!!, 0.0001f)
|
||||||
|
assertNull(nodeProgress(listOf(song("s3", "Three", "ar1", "Artist", "al1", "Album", size = 1))))
|
||||||
|
}
|
||||||
|
|
||||||
private fun song(
|
private fun song(
|
||||||
id: String,
|
id: String,
|
||||||
title: String,
|
title: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user