music: improve sorting

Update sorting usage in-app so that it's only done when absolutely
necessary.
This commit is contained in:
Alexander Capehart 2023-05-25 13:45:34 -06:00
parent c2def19aee
commit b037cfb166
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
8 changed files with 35 additions and 39 deletions

View file

@ -11,8 +11,10 @@
"appears on" section in the artist view
#### What's Fixed
- Prevented options such as "Add to queue" from being selected on empty
artists and playlists
- Prevented options such as "Add to queue" from being selected on empty artists and playlists
- Fixed issue where an item would be indicated as "playing" after playback ended
- Items should no longer be indicated as playing if the currently playing song is not contained
within it
## 3.1.0

View file

@ -430,9 +430,7 @@ constructor(
val list = mutableListOf<Item>()
val grouping =
Sort(Sort.Mode.ByDate, Sort.Direction.DESCENDING)
.albums(artist.explicitAlbums)
.groupByTo(sortedMapOf()) {
artist.explicitAlbums.groupByTo(sortedMapOf()) {
// Remap the complicated ReleaseType data structure into an easier
// "AlbumGrouping" enum that will automatically group and sort
// the artist's albums.
@ -458,7 +456,7 @@ constructor(
// implicit album list into the mapping.
@Suppress("UNCHECKED_CAST")
(grouping as MutableMap<AlbumGrouping, List<Album>>)[AlbumGrouping.APPEARANCES] =
Sort(Sort.Mode.ByDate, Sort.Direction.DESCENDING).albums(artist.implicitAlbums)
artist.implicitAlbums
}
logD("Release groups for this artist: ${grouping.keys}")

View file

@ -29,6 +29,7 @@ import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.getPlural
import org.oxycblt.auxio.util.inflater
import org.oxycblt.auxio.util.logD
/**
* A [DetailHeaderAdapter] that shows [Artist] information.
@ -91,6 +92,7 @@ private constructor(private val binding: ItemDetailHeaderBinding) :
// The artist does not have any songs, so hide functionality that makes no sense.
// ex. Play and Shuffle, Song Counts, and Genre Information.
// Artists are always guaranteed to have albums however, so continue to show those.
logD("Artist is empty, disabling genres and playback")
binding.detailSubhead.isVisible = false
binding.detailPlayButton.isEnabled = false
binding.detailShuffleButton.isEnabled = false

View file

@ -83,7 +83,6 @@ private constructor(private val binding: ItemDetailHeaderBinding) :
editedPlaylist: List<Song>?,
listener: DetailHeaderAdapter.Listener
) {
// TODO: Debug perpetually re-binding images
binding.detailCover.bind(playlist, editedPlaylist)
binding.detailType.text = binding.context.getString(R.string.lbl_playlist)
binding.detailName.text = playlist.name.resolve(binding.context)

View file

@ -50,6 +50,7 @@ import okio.buffer
import okio.source
import org.oxycblt.auxio.image.CoverMode
import org.oxycblt.auxio.image.ImageSettings
import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.util.logD
@ -81,7 +82,12 @@ constructor(
}
fun computeAlbumOrdering(songs: List<Song>) =
songs.groupBy { it.album }.entries.sortedByDescending { it.value.size }.map { it.key }
Sort(Sort.Mode.ByAlbum, Sort.Direction.ASCENDING)
.songs(songs)
.groupBy { it.album }
.entries
.sortedByDescending { it.value.size }
.map { it.key }
private suspend fun openInputStream(album: Album): InputStream? =
try {

View file

@ -341,8 +341,6 @@ interface Artist : MusicParent {
* @author Alexander Capehart (OxygenCobalt)
*/
interface Genre : MusicParent {
/** The albums indirectly linked to by the [Song]s of this [Genre]. */
val albums: List<Album>
/** The artists indirectly linked to by the [Artist]s of this [Genre]. */
val artists: List<Artist>
/** The total duration of the songs in this genre, in milliseconds. */
@ -355,8 +353,6 @@ interface Genre : MusicParent {
* @author Alexander Capehart (OxygenCobalt)
*/
interface Playlist : MusicParent {
/** The albums indirectly linked to by the [Song]s of this [Playlist]. */
val albums: List<Album>
/** The total duration of the songs in this genre, in milliseconds. */
val durationMs: Long
}

View file

@ -387,9 +387,9 @@ class ArtistImpl(
}
songs = distinctSongs.toList()
albums = albumMap.keys.toList()
explicitAlbums = albumMap.entries.filter { it.value }.map { it.key }
implicitAlbums = albumMap.entries.filterNot { it.value }.map { it.key }
albums = Sort(Sort.Mode.ByDate, Sort.Direction.DESCENDING).albums(albumMap.keys)
explicitAlbums = albums.filter { unlikelyToBeNull(albumMap[it]) }
implicitAlbums = albums.filterNot { unlikelyToBeNull(albumMap[it]) }
durationMs = songs.sumOf { it.durationMs }.nonZeroOrNull()
}
@ -436,7 +436,6 @@ class GenreImpl(
rawGenre.name?.let { Name.Known.from(it, rawGenre.name, musicSettings) }
?: Name.Unknown(R.string.def_genre)
override val albums: List<Album>
override val artists: List<Artist>
override val durationMs: Long
@ -462,10 +461,6 @@ class GenreImpl(
totalDuration += song.durationMs
}
albums =
Sort(Sort.Mode.ByName, Sort.Direction.ASCENDING)
.albums(distinctAlbums)
.sortedByDescending { album -> album.songs.count { it.genres.contains(this) } }
artists = Sort(Sort.Mode.ByName, Sort.Direction.ASCENDING).artists(distinctArtists)
durationMs = totalDuration
}

View file

@ -33,8 +33,6 @@ private constructor(
override val songs: List<Song>
) : Playlist {
override val durationMs = songs.sumOf { it.durationMs }
override val albums =
songs.groupBy { it.album }.entries.sortedByDescending { it.value.size }.map { it.key }
/**
* Clone the data in this instance to a new [PlaylistImpl] with the given [name].