music: improve sorting
Update sorting usage in-app so that it's only done when absolutely necessary.
This commit is contained in:
parent
c2def19aee
commit
b037cfb166
8 changed files with 35 additions and 39 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -430,27 +430,25 @@ constructor(
|
|||
val list = mutableListOf<Item>()
|
||||
|
||||
val grouping =
|
||||
Sort(Sort.Mode.ByDate, Sort.Direction.DESCENDING)
|
||||
.albums(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.
|
||||
when (it.releaseType.refinement) {
|
||||
ReleaseType.Refinement.LIVE -> AlbumGrouping.LIVE
|
||||
ReleaseType.Refinement.REMIX -> AlbumGrouping.REMIXES
|
||||
null ->
|
||||
when (it.releaseType) {
|
||||
is ReleaseType.Album -> AlbumGrouping.ALBUMS
|
||||
is ReleaseType.EP -> AlbumGrouping.EPS
|
||||
is ReleaseType.Single -> AlbumGrouping.SINGLES
|
||||
is ReleaseType.Compilation -> AlbumGrouping.COMPILATIONS
|
||||
is ReleaseType.Soundtrack -> AlbumGrouping.SOUNDTRACKS
|
||||
is ReleaseType.Mix -> AlbumGrouping.DJMIXES
|
||||
is ReleaseType.Mixtape -> AlbumGrouping.MIXTAPES
|
||||
}
|
||||
}
|
||||
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.
|
||||
when (it.releaseType.refinement) {
|
||||
ReleaseType.Refinement.LIVE -> AlbumGrouping.LIVE
|
||||
ReleaseType.Refinement.REMIX -> AlbumGrouping.REMIXES
|
||||
null ->
|
||||
when (it.releaseType) {
|
||||
is ReleaseType.Album -> AlbumGrouping.ALBUMS
|
||||
is ReleaseType.EP -> AlbumGrouping.EPS
|
||||
is ReleaseType.Single -> AlbumGrouping.SINGLES
|
||||
is ReleaseType.Compilation -> AlbumGrouping.COMPILATIONS
|
||||
is ReleaseType.Soundtrack -> AlbumGrouping.SOUNDTRACKS
|
||||
is ReleaseType.Mix -> AlbumGrouping.DJMIXES
|
||||
is ReleaseType.Mixtape -> AlbumGrouping.MIXTAPES
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (artist.implicitAlbums.isNotEmpty()) {
|
||||
// groupByTo normally returns a mapping to a MutableList mapping. Since MutableList
|
||||
|
@ -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}")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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].
|
||||
|
|
Loading…
Reference in a new issue